render palette, update led strip

Signed-off-by: dragonchaser <christian@boltares.de>
This commit is contained in:
dragonchaser
2025-07-10 17:01:58 +02:00
parent b02614bd04
commit 2969ed4ebe

View File

@@ -18,10 +18,12 @@
#define FRAMES_PER_SECOND 24 #define FRAMES_PER_SECOND 24
#define MAX_VANISH_COUNTER 50 #define MAX_VANISH_COUNTER 50
#define MAX_MONITOR_DEVICES 10 #define MAX_MONITOR_DEVICES 100
CRGB leds[NUM_LEDS]; CRGB leds[NUM_LEDS];
CRGBPalette256 pal;
int scanTime = 1; //In seconds int scanTime = 1; //In seconds
BLEScan *pBLEScan; BLEScan *pBLEScan;
@@ -29,22 +31,26 @@ BLEScan *pBLEScan;
std::map<String,uint8_t> deviceDatabase; std::map<String,uint8_t> deviceDatabase;
std::mutex callBackMutex; 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 { class AdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks {
void onResult(BLEAdvertisedDevice advertisedDevice) { 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 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.toUpperCase();
color[1] = 'x';
if (deviceDatabase.contains(color) || deviceDatabase.size() + 1 < MAX_MONITOR_DEVICES) { if (deviceDatabase.contains(color) || deviceDatabase.size() + 1 < MAX_MONITOR_DEVICES) {
deviceDatabase[color] = MAX_VANISH_COUNTER; 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()); 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<NUM_LEDS;i++) {
leds[i] = strtol(color.c_str(), NULL, 0);
}
std::vector<String> keys; std::vector<String> keys;
for (auto &itr : deviceDatabase) { for (auto &itr : deviceDatabase) {
if (color != itr.first) { 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("Have not seen %s for %d ticks, removing!\n", itr, MAX_VANISH_COUNTER);
} }
Serial.printf("Devicedatabase size: %d\n", deviceDatabase.size()); Serial.printf("Devicedatabase size: %d\n", deviceDatabase.size());
updatePalette();
} }
}; };
void setup() { void setup() {
updatePalette();
FastLED.delay(1000/FRAMES_PER_SECOND); FastLED.delay(1000/FRAMES_PER_SECOND);
FastLED.addLeds<NEOPIXEL,DATA_PIN>(leds, NUM_LEDS); FastLED.addLeds<NEOPIXEL,DATA_PIN>(leds, NUM_LEDS);
for(int i=0; i<NUM_LEDS;i++) { for(int i=0; i<NUM_LEDS;i++) {
@@ -90,6 +98,8 @@ void setup() {
Serial.begin(115200); Serial.begin(115200);
Serial.println("Scanning..."); Serial.println("Scanning...");
startindex = 0;
BLEDevice::init(""); BLEDevice::init("");
pBLEScan = BLEDevice::getScan(); //create new scan pBLEScan = BLEDevice::getScan(); //create new scan
pBLEScan->setAdvertisedDeviceCallbacks(new AdvertisedDeviceCallbacks()); pBLEScan->setAdvertisedDeviceCallbacks(new AdvertisedDeviceCallbacks());
@@ -100,11 +110,83 @@ void setup() {
void loop() { void loop() {
{ {
std::lock_guard<std::mutex> lck(callBackMutex); std::lock_guard<std::mutex> lock(callBackMutex);
BLEScanResults *foundDevices = pBLEScan->start(scanTime, false); BLEScanResults *foundDevices = pBLEScan->start(scanTime, false);
pBLEScan->clearResults(); // delete results fromBLEScan buffer to release memory pBLEScan->clearResults(); // delete results fromBLEScan buffer to release memory
} }
FillLEDsFromPaletteColors(startindex++);
FastLED.show(); FastLED.show();
FastLED.delay(1000/FRAMES_PER_SECOND); 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<std::mutex> 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()));
} }