121 lines
4.5 KiB
C++
121 lines
4.5 KiB
C++
#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(); // если хочешь сразу сохранять
|
||
}
|