* POV Display usermod this usermod adds a new effect called "POV Image". To get it to work: - read the README :) - upload a bmp image to the ESP filesystem using "/edit" url. - select "POV Image" effect. - set the filename (ie: "/myimage.bmp") as segment name. - rotate the segment at approximately 20 RPM. - enjoy the show! * improve file extension checks * improve README, remove PNGdec reference, clean usermod * restrain to esp32 platform + reduce memory footprint with malloc
76 lines
2.0 KiB
C++
76 lines
2.0 KiB
C++
#include "wled.h"
|
|
#include "pov.h"
|
|
|
|
static const char _data_FX_MODE_POV_IMAGE[] PROGMEM = "POV Image@!;;;;";
|
|
|
|
static POV s_pov;
|
|
|
|
uint16_t mode_pov_image(void) {
|
|
Segment& mainseg = strip.getMainSegment();
|
|
const char* segName = mainseg.name;
|
|
if (!segName) {
|
|
return FRAMETIME;
|
|
}
|
|
// Only proceed for files ending with .bmp (case-insensitive)
|
|
size_t segLen = strlen(segName);
|
|
if (segLen < 4) return FRAMETIME;
|
|
const char* ext = segName + (segLen - 4);
|
|
// compare case-insensitive to ".bmp"
|
|
if (!((ext[0]=='.') &&
|
|
(ext[1]=='b' || ext[1]=='B') &&
|
|
(ext[2]=='m' || ext[2]=='M') &&
|
|
(ext[3]=='p' || ext[3]=='P'))) {
|
|
return FRAMETIME;
|
|
}
|
|
|
|
const char* current = s_pov.getFilename();
|
|
if (current && strcmp(segName, current) == 0) {
|
|
s_pov.showNextLine();
|
|
return FRAMETIME;
|
|
}
|
|
|
|
static unsigned long s_lastLoadAttemptMs = 0;
|
|
unsigned long nowMs = millis();
|
|
// Retry at most twice per second if the image is not yet loaded.
|
|
if (nowMs - s_lastLoadAttemptMs < 500) return FRAMETIME;
|
|
s_lastLoadAttemptMs = nowMs;
|
|
s_pov.loadImage(segName);
|
|
return FRAMETIME;
|
|
}
|
|
|
|
class PovDisplayUsermod : public Usermod {
|
|
protected:
|
|
bool enabled = false; //WLEDMM
|
|
const char *_name; //WLEDMM
|
|
bool initDone = false; //WLEDMM
|
|
unsigned long lastTime = 0; //WLEDMM
|
|
public:
|
|
|
|
PovDisplayUsermod(const char *name, bool enabled)
|
|
: enabled(enabled) , _name(name) {}
|
|
|
|
void setup() override {
|
|
strip.addEffect(255, &mode_pov_image, _data_FX_MODE_POV_IMAGE);
|
|
//initDone removed (unused)
|
|
}
|
|
|
|
|
|
void loop() override {
|
|
// if usermod is disabled or called during strip updating just exit
|
|
// NOTE: on very long strips strip.isUpdating() may always return true so update accordingly
|
|
if (!enabled || strip.isUpdating()) return;
|
|
|
|
// do your magic here
|
|
if (millis() - lastTime > 1000) {
|
|
lastTime = millis();
|
|
}
|
|
}
|
|
|
|
uint16_t getId() override {
|
|
return USERMOD_ID_POV_DISPLAY;
|
|
}
|
|
};
|
|
|
|
static PovDisplayUsermod pov_display("POV Display", false);
|
|
REGISTER_USERMOD(pov_display);
|