From 75008f03d7c25563c63424a31593709d231dad49 Mon Sep 17 00:00:00 2001 From: Razvalyaev Date: Wed, 21 May 2025 00:44:51 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B0=20=D0=BF=D0=BE=D0=B4=D0=B4=D0=B5=D1=80=D0=B6=D0=BA?= =?UTF-8?q?=D0=B0=20=D0=BF=D0=BE=D0=B4=D1=81=D1=82=D0=B2=D0=B5=D1=82=D0=BA?= =?UTF-8?q?=D0=B8=20=D1=87=D0=B5=D1=80=D0=B5=D0=B7=20ble=20=D0=B8=20=D0=BE?= =?UTF-8?q?=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5=D0=BD=D1=8B=20=D0=B1=D0=B8?= =?UTF-8?q?=D0=B1=D0=BB=D0=B8=D0=BE=D1=82=D0=B5=D0=BA=D0=B8=20(=D0=BD?= =?UTF-8?q?=D0=BE=20=D1=82=D0=B5=D0=BF=D0=B5=D1=80=D1=8C=20=D0=BC=D1=8B?= =?UTF-8?q?=D1=88=D0=BA=D0=B0=20=D0=BD=D0=B5=20=D1=80=D0=B0=D0=B1=D0=BE?= =?UTF-8?q?=D1=82=D0=B0=D0=B5=D1=82=20=D0=BA=D0=B0=D0=BA=20=D0=BC=D1=8B?= =?UTF-8?q?=D1=88=D0=BA=D0=B0)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mouse/ESP32-BLE-Mouse-master.zip | Bin 8374 -> 8568 bytes mouse/LedControl.cpp | 120 +++++++++++++++++++++++++++++++ mouse/LedControl.h | 81 +++++++++++++++++++++ mouse/mouse.ino | 53 +++++++++++--- 4 files changed, 245 insertions(+), 9 deletions(-) create mode 100644 mouse/LedControl.cpp create mode 100644 mouse/LedControl.h diff --git a/mouse/ESP32-BLE-Mouse-master.zip b/mouse/ESP32-BLE-Mouse-master.zip index 70c4ff4add601b72a57c77a3b2e30260e9c33ff6..1b6280862749a3d943f4e7993596fee8dbb06456 100644 GIT binary patch delta 3286 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 XgAqUf<-15LK-3@r07cPLq?P{#^DoYC delta 3028 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 z + +void LedControl::begin() { + rgbLed.begin(); + loadSettings(); + applyColor(); +} + +// Вспомогательная функция для создания дескриптора с описанием +BLEDescriptor* createUserDescription(const char* description) { + BLEDescriptor* desc = new BLEDescriptor(BLEUUID((uint16_t)0x2901)); + desc->setValue(description); + return desc; +} + +// Вспомогательная функция для создания дескриптора формата uint8 +BLEDescriptor* createPresentationFormatDescriptor() { + // Формат Presentation Format Descriptor (0x2904) + // Format: uint8 (0x04), Exponent: 0, Unit: unitless (0x2700), Namespace: Bluetooth SIG (1), Description: 0 + uint8_t presentationFormat[7] = { + 0x04, // Format: uint8 + 0x00, // Exponent + 0x00, 0x27, // Unit (unitless) - обратите внимание на порядок байт: младший сначала + 0x01, // Namespace (Bluetooth SIG) + 0x00, 0x00 // Description + }; + BLEDescriptor* desc = new BLEDescriptor(BLEUUID((uint16_t)0x2904)); + desc->setValue(presentationFormat, sizeof(presentationFormat)); + return desc; +} +void LedControl::setupBLEService(BLEServer *server) { + BLEService *colorService = server->createService(COLOR_SERVICE_UUID); + + // --- Красный --- + BLECharacteristic *rChar = colorService->createCharacteristic( + COLOR_CHAR_R_UUID, + BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_WRITE + ); + rChar->setAccessPermissions(ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE); + rChar->setValue(currentR); + rChar->setCallbacks(new ColorCallbacks(this, 0)); + // rChar->addDescriptor(createUserDescription("Red")); + + // --- Зелёный --- + BLECharacteristic *gChar = colorService->createCharacteristic( + COLOR_CHAR_G_UUID, + BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_WRITE + ); + gChar->setAccessPermissions(ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE); + gChar->setValue(currentG); + gChar->setCallbacks(new ColorCallbacks(this, 1)); + // gChar->addDescriptor(createUserDescription("Green")); + + // --- Синий --- + BLECharacteristic *bChar = colorService->createCharacteristic( + COLOR_CHAR_B_UUID, + BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_WRITE + ); + bChar->setAccessPermissions(ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE); + bChar->setValue(currentB); + bChar->setCallbacks(new ColorCallbacks(this, 2)); + // bChar->addDescriptor(createUserDescription("Blue")); + + // --- Яркость --- + BLECharacteristic *brChar = colorService->createCharacteristic( + COLOR_CHAR_BRIGHTNESS_UUID, + BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_WRITE + ); + brChar->setAccessPermissions(ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE); + brChar->setValue(currentBrightness); + brChar->setCallbacks(new ColorCallbacks(this, 3)); + // brChar->addDescriptor(createUserDescription("Brightness")); + + colorService->start(); + + BLEAdvertising *advertising = BLEDevice::getAdvertising(); + advertising->addServiceUUID(COLOR_SERVICE_UUID); +} + + +void LedControl::loadSettings() { + preferences.begin(LED_NAMESPACE, true); + currentR = preferences.getUChar("r", 0); + currentG = preferences.getUChar("g", 0); + currentB = preferences.getUChar("b", 0); + currentBrightness = preferences.getUChar("br", 0); + preferences.end(); +} + +void LedControl::saveSettings() { + preferences.begin(LED_NAMESPACE, false); + preferences.putUChar("r", currentR); + preferences.putUChar("g", currentG); + preferences.putUChar("b", currentB); + preferences.putUChar("br", currentBrightness); + preferences.end(); +} + +void LedControl::applyColor() { + rgbLed.setPixelColor(0, rgbLed.Color(currentR, currentG, currentB)); + rgbLed.setBrightness(correctedBrightness(currentBrightness)); + rgbLed.show(); +} + +uint8_t LedControl::correctedBrightness(uint8_t percent) { + if (percent > 100) percent = 100; + const float gamma = 2.2f; + return pow(percent / 100.0f, gamma) * 255; +} +void LedControl::forceColor(uint8_t r, uint8_t g, uint8_t b) +{ + currentR = r; + currentG = g; + currentB = b; + rgbLed.setPixelColor(0, rgbLed.Color(r, g, b)); + rgbLed.setBrightness(correctedBrightness(currentBrightness)); + rgbLed.show(); + saveSettings(); // если хочешь сразу сохранять +} diff --git a/mouse/LedControl.h b/mouse/LedControl.h new file mode 100644 index 0000000..77f55f7 --- /dev/null +++ b/mouse/LedControl.h @@ -0,0 +1,81 @@ +#ifndef LED_CONTROL_H +#define LED_CONTROL_H + +#include +#include +#include +#include +#include +#include + +#define LED_NAMESPACE "led" +#define COLOR_SERVICE_UUID "12345678-1234-5678-1234-56789abcdef0" +#define COLOR_CHAR_R_UUID "12345678-1234-5678-1234-56789abcdef1" +#define COLOR_CHAR_G_UUID "12345678-1234-5678-1234-56789abcdef2" +#define COLOR_CHAR_B_UUID "12345678-1234-5678-1234-56789abcdef3" +#define COLOR_CHAR_BRIGHTNESS_UUID "12345678-1234-5678-1234-56789abcdef4" + +class LedControl { +public: + LedControl(Adafruit_NeoPixel &led) + : rgbLed(led) {} + + void begin(); + void setupBLEService(BLEServer *server); + void applyColor(); + void forceColor(uint8_t r, uint8_t g, uint8_t b); + +private: + Adafruit_NeoPixel &rgbLed; + Preferences preferences; + + int currentR = 0, currentG = 0, currentB = 0, currentBrightness = 50; + BLECharacteristic *colorCharacteristic = nullptr; + + void loadSettings(); + void saveSettings(); + uint8_t correctedBrightness(uint8_t percent); + +class ColorCallbacks : public BLECharacteristicCallbacks { +public: + ColorCallbacks(LedControl *parent, uint8_t paramId) + : _parent(parent), _paramId(paramId) {} + + void onWrite(BLECharacteristic *characteristic) override { + String value = characteristic->getValue(); + if (value.length() >= 1) { + uint8_t val = static_cast(value[0]); + switch (_paramId) { + case 0: _parent->currentR = val; break; + case 1: _parent->currentG = val; break; + case 2: _parent->currentB = val; break; + case 3: _parent->currentBrightness = val; break; + } + characteristic->setValue(&val, 1); + _parent->applyColor(); + _parent->saveSettings(); + + Serial.printf("Set param %d = %d\n", _paramId, val); + } + } + + void onRead(BLECharacteristic *characteristic) override { + uint8_t val = 0; + switch (_paramId) { + case 0: val = _parent->currentR; break; + case 1: val = _parent->currentG; break; + case 2: val = _parent->currentB; break; + case 3: val = _parent->currentBrightness; break; + } + characteristic->setValue(&val, 1); // Обновляем значение характеристики перед чтением + + Serial.printf("Read param %d value: %d\n", _paramId, val); + } + +private: + LedControl *_parent; + uint8_t _paramId; +}; + +}; +#endif diff --git a/mouse/mouse.ino b/mouse/mouse.ino index 45318e7..e6fcd9e 100644 --- a/mouse/mouse.ino +++ b/mouse/mouse.ino @@ -1,13 +1,21 @@ #include #include "EspUsbHost.h" +#include +#define LED_PIN 21 // GPIO пин светодиода (скорее всего 48) +#define NUM_LEDS 1 // Один RGB светодиод #define SHOW_REAL_BATTERY -#define DISABLE_USB - +// #define RGB_LED +// #define DISABLE_USB BleMouse bleMouse("Ball Mouse"); +#ifdef RGB_LED +Adafruit_NeoPixel rgbLed(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800); +LedControl ledControl(rgbLed); +#endif //RGB_LED + #ifdef SHOW_REAL_BATTERY #define BATTERY_UPDATE_INTERVAL 5000 // например, 30000 мс = 30 секунд #define BATTERY_ADC_PIN 6 @@ -51,17 +59,44 @@ MyEspUsbHost usbHost; #endif //DISABLE_USB void setup() { - Serial.begin(115200); - delay(500); - + // Serial.begin(115200); +#ifdef RGB_LED + // Запуск мыши — зелёный + ledControl.begin(); + ledControl.forceColor(0, 255, 0); // Зеленый +#endif//RGB_LED +#ifdef RGB_LED + // Инициализация BLE - красный + ledControl.forceColor(255, 0, 0); // Красный +#endif//RGB_LED + // Запуск BLE мыши (HID) + bleMouse.init(); + // Создаём BLE-сервер для подстветки + BLEServer *server = BLEDevice::createServer(); +#ifdef RGB_LED + // Настройка кастомного сервиса цвета + ledControl.setupBLEService(server); + // Добавляем UUID нашего сервиса в рекламу (важно до start) + BLEAdvertising *advertising = BLEDevice::getAdvertising(); + advertising->addServiceUUID(COLOR_SERVICE_UUID); +#endif//RGB_LED + // Запуск BLE мыши (HID) bleMouse.begin(); - Serial.println("BLE Mouse started"); + // BLE готов — красный +#ifdef RGB_LED + // USB — синий + ledControl.forceColor(0, 0, 255); // Синий +#endif//RGB_LED #ifndef DISABLE_USB usbHost.begin(); - Serial.println("USB Host started"); -#endif //DISABLE_USB +#endif + +#ifdef RGB_LED + // Загрузка сохранённого цвета + ledControl.applyColor(); +#endif//RGB_LED } void loop() { @@ -84,4 +119,4 @@ void loop() { } } #endif -} +} \ No newline at end of file