Добавлена поддержка подстветки через ble и обновлены библиотеки (но теперь мышка не работает как мышка)
This commit is contained in:
parent
0ba7500cd1
commit
75008f03d7
Binary file not shown.
120
mouse/LedControl.cpp
Normal file
120
mouse/LedControl.cpp
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
#include "LedControl.h"
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
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(); // если хочешь сразу сохранять
|
||||||
|
}
|
81
mouse/LedControl.h
Normal file
81
mouse/LedControl.h
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
#ifndef LED_CONTROL_H
|
||||||
|
#define LED_CONTROL_H
|
||||||
|
|
||||||
|
#include <Adafruit_NeoPixel.h>
|
||||||
|
#include <Preferences.h>
|
||||||
|
#include <BLECharacteristic.h>
|
||||||
|
#include <BLEServer.h>
|
||||||
|
#include <BLEDevice.h>
|
||||||
|
#include <BleMouse.h>
|
||||||
|
|
||||||
|
#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<uint8_t>(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
|
@ -1,13 +1,21 @@
|
|||||||
#include <BleMouse.h>
|
#include <BleMouse.h>
|
||||||
#include "EspUsbHost.h"
|
#include "EspUsbHost.h"
|
||||||
|
#include <LedControl.h>
|
||||||
|
|
||||||
|
#define LED_PIN 21 // GPIO пин светодиода (скорее всего 48)
|
||||||
|
#define NUM_LEDS 1 // Один RGB светодиод
|
||||||
|
|
||||||
#define SHOW_REAL_BATTERY
|
#define SHOW_REAL_BATTERY
|
||||||
#define DISABLE_USB
|
// #define RGB_LED
|
||||||
|
// #define DISABLE_USB
|
||||||
|
|
||||||
BleMouse bleMouse("Ball Mouse");
|
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
|
#ifdef SHOW_REAL_BATTERY
|
||||||
#define BATTERY_UPDATE_INTERVAL 5000 // например, 30000 мс = 30 секунд
|
#define BATTERY_UPDATE_INTERVAL 5000 // например, 30000 мс = 30 секунд
|
||||||
#define BATTERY_ADC_PIN 6
|
#define BATTERY_ADC_PIN 6
|
||||||
@ -51,17 +59,44 @@ MyEspUsbHost usbHost;
|
|||||||
#endif //DISABLE_USB
|
#endif //DISABLE_USB
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
Serial.begin(115200);
|
// Serial.begin(115200);
|
||||||
delay(500);
|
#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();
|
bleMouse.begin();
|
||||||
Serial.println("BLE Mouse started");
|
// BLE готов — красный
|
||||||
|
|
||||||
|
#ifdef RGB_LED
|
||||||
|
// USB — синий
|
||||||
|
ledControl.forceColor(0, 0, 255); // Синий
|
||||||
|
#endif//RGB_LED
|
||||||
#ifndef DISABLE_USB
|
#ifndef DISABLE_USB
|
||||||
usbHost.begin();
|
usbHost.begin();
|
||||||
Serial.println("USB Host started");
|
#endif
|
||||||
#endif //DISABLE_USB
|
|
||||||
|
#ifdef RGB_LED
|
||||||
|
// Загрузка сохранённого цвета
|
||||||
|
ledControl.applyColor();
|
||||||
|
#endif//RGB_LED
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
|
Loading…
Reference in New Issue
Block a user