From 2969ed4ebed1bda6ce2fc7f799d12f1030cea411 Mon Sep 17 00:00:00 2001 From: dragonchaser Date: Thu, 10 Jul 2025 17:01:58 +0200 Subject: [PATCH] render palette, update led strip Signed-off-by: dragonchaser --- btcontrol.ino | 98 ++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 90 insertions(+), 8 deletions(-) diff --git a/btcontrol.ino b/btcontrol.ino index 8842a06..7f63352 100644 --- a/btcontrol.ino +++ b/btcontrol.ino @@ -18,10 +18,12 @@ #define FRAMES_PER_SECOND 24 #define MAX_VANISH_COUNTER 50 -#define MAX_MONITOR_DEVICES 10 +#define MAX_MONITOR_DEVICES 100 CRGB leds[NUM_LEDS]; +CRGBPalette256 pal; + int scanTime = 1; //In seconds BLEScan *pBLEScan; @@ -29,22 +31,26 @@ BLEScan *pBLEScan; std::map deviceDatabase; std::mutex callBackMutex; +std::mutex blendMutex; -CRGBPalette16 MyPalette; +volatile uint8_t startindex; +volatile uint8_t stepSegments; + +void updatePalette(); +uint64_t StrToHex(const char* str); +CRGB blendCRGB(CRGB a, CRGB b, uint8_t blendAmount); +void FillLEDsFromPaletteColors( uint8_t colorIndex); class AdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks { void onResult(BLEAdvertisedDevice advertisedDevice) { + // TODO: switching of does not work because this function is only triggered when new devices are detected, ergo it will always be stuck with the last device String addr = advertisedDevice.getAddress().toString(); - String color = String("0x"+addr.substring(9,11)+addr.substring(12,14)+addr.substring(15,17)); + String color = String(addr.substring(9,11)+addr.substring(12,14)+addr.substring(15,17)); color.toUpperCase(); - color[1] = 'x'; if (deviceDatabase.contains(color) || deviceDatabase.size() + 1 < MAX_MONITOR_DEVICES) { deviceDatabase[color] = MAX_VANISH_COUNTER; } Serial.printf("Address: %s RSSI: %d TX Power: %d Calculated color: %s \n", addr.c_str(), advertisedDevice.getRSSI(), advertisedDevice.getTXPower(), color.c_str()); - for(int i=0; i keys; for (auto &itr : deviceDatabase) { if (color != itr.first) { @@ -59,10 +65,12 @@ class AdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks { Serial.printf("Have not seen %s for %d ticks, removing!\n", itr, MAX_VANISH_COUNTER); } Serial.printf("Devicedatabase size: %d\n", deviceDatabase.size()); + updatePalette(); } }; void setup() { + updatePalette(); FastLED.delay(1000/FRAMES_PER_SECOND); FastLED.addLeds(leds, NUM_LEDS); for(int i=0; isetAdvertisedDeviceCallbacks(new AdvertisedDeviceCallbacks()); @@ -100,11 +110,83 @@ void setup() { void loop() { { - std::lock_guard lck(callBackMutex); + std::lock_guard lock(callBackMutex); BLEScanResults *foundDevices = pBLEScan->start(scanTime, false); pBLEScan->clearResults(); // delete results fromBLEScan buffer to release memory } + FillLEDsFromPaletteColors(startindex++); FastLED.show(); FastLED.delay(1000/FRAMES_PER_SECOND); +} + +uint64_t StrToHex(const char* str) +{ + return (uint64_t) strtoull(str, 0, 16); +} + +void FillLEDsFromPaletteColors( uint8_t colorIndex) +{ + uint8_t brightness = 255; + + for( int i = 0; i < NUM_LEDS; ++i) { + leds[i] = ColorFromPalette( pal, colorIndex, brightness, LINEARBLEND); + colorIndex += stepSegments; + } +} + +// Blends two CRGB colors using a uint8_t blend amount (0-255) +CRGB blendCRGB(CRGB a, CRGB b, uint8_t blendAmount) { + CRGB result; + result.r = lerp8by8(a.r, b.r, blendAmount); + result.g = lerp8by8(a.g, b.g, blendAmount); + result.b = lerp8by8(a.b, b.b, blendAmount); + return result; +} + +void updatePalette() { + std::lock_guard lock(blendMutex); + uint8_t numColors = 2; + String colors[MAX_MONITOR_DEVICES]; + switch (deviceDatabase.size()) { + case 0: + numColors = 2; + colors[0] = "000000"; + colors[1] = "000000"; + case 1: + numColors = 2; + colors[0] = deviceDatabase.begin()->first.substring(2,8); + colors[1] = deviceDatabase.begin()->first.substring(2,8); + break; + default: + numColors = deviceDatabase.size(); + int pos = 0 ; + for (auto itr: deviceDatabase) { + colors[pos++] = itr.first.substring(2,8); + } + break; + } + uint8_t segmentSize = 255 / (numColors - 1); // Divide the palette into segments + + if(numColors < 1) { + Serial.println("Less than 2 colors? Something is fucky?"); + } + for (uint8_t i = 0; i < numColors - 1; i++) { + CRGB startColor = CRGB(StrToHex(colors[i].c_str())); + CRGB endColor = CRGB(StrToHex(colors[i + 1].c_str())); + + for (uint8_t j = 0; j < segmentSize; j++) { + uint16_t index = i * segmentSize + j; + if (index >= 256) break; + + uint8_t blendAmount = (j * 255) / segmentSize; // Integer blend factor + pal[index] = blendCRGB(startColor, endColor, blendAmount); + + if (index % 16 == 0) yield(); // Prevent watchdog reset + } + } + stepSegments = segmentSize; + + // Make sure the last color slot is correctly set + pal[255] = CRGB(StrToHex(colors[numColors - 1].c_str())); } \ No newline at end of file