Merge pull request #3539 from Liliputech/pov_display

Added POV image effect
This commit is contained in:
Blaž Kristan 2024-08-18 13:15:34 +02:00 committed by GitHub
commit 72d38f4cff
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 98 additions and 0 deletions

View File

@ -29,6 +29,8 @@ lib_deps = ${esp8266.lib_deps}
; ;gmag11/QuickESPNow @ ~0.7.0 # will also load QuickDebug
; https://github.com/blazoncek/QuickESPNow.git#optional-debug ;; exludes debug library
; ${esp32.AR_lib_deps} ;; used for USERMOD_AUDIOREACTIVE
; bitbank2/PNGdec@^1.0.1 ;; used for POV display uncomment following
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp8266.build_flags}
;
@ -152,6 +154,8 @@ build_flags = ${common.build_flags} ${esp8266.build_flags}
; -D TACHO_PIN=33
; -D PWM_PIN=32
;
; Use POV Display usermod
; -D USERMOD_POV_DISPLAY
; Use built-in or custom LED as a status indicator (assumes LED is connected to GPIO16)
; -D STATUSLED=16
;

View File

@ -0,0 +1,85 @@
#pragma once
#include "wled.h"
#include <PNGdec.h>
void * openFile(const char *filename, int32_t *size) {
f = WLED_FS.open(filename);
*size = f.size();
return &f;
}
void closeFile(void *handle) {
if (f) f.close();
}
int32_t readFile(PNGFILE *pFile, uint8_t *pBuf, int32_t iLen)
{
int32_t iBytesRead;
iBytesRead = iLen;
File *f = static_cast<File *>(pFile->fHandle);
// Note: If you read a file all the way to the last byte, seek() stops working
if ((pFile->iSize - pFile->iPos) < iLen)
iBytesRead = pFile->iSize - pFile->iPos - 1; // <-- ugly work-around
if (iBytesRead <= 0)
return 0;
iBytesRead = (int32_t)f->read(pBuf, iBytesRead);
pFile->iPos = f->position();
return iBytesRead;
}
int32_t seekFile(PNGFILE *pFile, int32_t iPosition)
{
int i = micros();
File *f = static_cast<File *>(pFile->fHandle);
f->seek(iPosition);
pFile->iPos = (int32_t)f->position();
i = micros() - i;
return pFile->iPos;
}
void draw(PNGDRAW *pDraw) {
uint16_t usPixels[SEGLEN];
png.getLineAsRGB565(pDraw, usPixels, PNG_RGB565_LITTLE_ENDIAN, 0xffffffff);
for(int x=0; x < SEGLEN; x++) {
uint16_t color = usPixels[x];
byte r = ((color >> 11) & 0x1F);
byte g = ((color >> 5) & 0x3F);
byte b = (color & 0x1F);
SEGMENT.setPixelColor(x, RGBW32(r,g,b,0));
}
strip.show();
}
uint16_t mode_pov_image(void) {
const char * filepath = SEGMENT.name;
int rc = png.open(filepath, openFile, closeFile, readFile, seekFile, draw);
if (rc == PNG_SUCCESS) {
rc = png.decode(NULL, 0);
png.close();
return FRAMETIME;
}
return FRAMETIME;
}
class PovDisplayUsermod : public Usermod
{
public:
static const char _data_FX_MODE_POV_IMAGE[] PROGMEM = "POV Image@!;;;1";
PNG png;
File f;
void setup() {
strip.addEffect(255, &mode_pov_image, _data_FX_MODE_POV_IMAGE);
}
void loop() {
}
uint16_t getId()
{
return USERMOD_ID_POV_DISPLAY;
}
void connected() {}
};

View File

@ -200,6 +200,7 @@
#define USERMOD_ID_INA226 50 //Usermod "usermod_ina226.h"
#define USERMOD_ID_AHT10 51 //Usermod "usermod_aht10.h"
#define USERMOD_ID_LD2410 52 //Usermod "usermod_ld2410.h"
#define USERMOD_ID_POV_DISPLAY 53 //Usermod "usermod_pov_display.h"
//Access point behavior
#define AP_BEHAVIOR_BOOT_NO_CONN 0 //Open AP when no connection after boot

View File

@ -210,6 +210,10 @@
#include "../usermods/LDR_Dusk_Dawn_v2/usermod_LDR_Dusk_Dawn_v2.h"
#endif
#ifdef USERMOD_POV_DISPLAY
#include "../usermods/pov_display/usermod_pov_display.h"
#endif
#ifdef USERMOD_STAIRCASE_WIPE
#include "../usermods/stairway_wipe_basic/stairway-wipe-usermod-v2.h"
#endif
@ -454,4 +458,8 @@ void registerUsermods()
#ifdef USERMOD_LD2410
usermods.add(new LD2410Usermod());
#endif
#ifdef USERMOD_POV_DISPLAY
usermods.add(new PovDisplayUsermod());
#endif
}