TV Simulator Effect (#1548)
* New Effect "TV Simulator" based on "Fake TV Light for Engineers" by Phillip Burgess https://learn.adafruit.com/fake-tv-light-for-engineers/arduino-sketch * removed some not-used functions ...from my 1st attempt with "Phoney TV" - but this one did not look good. * Created new version of tv_colors.h based on 18 movies ...and some corrections * Add include guards for tv_colors.h and disable option Co-authored-by: cschwinne <dev.aircoookie@gmail.com>
This commit is contained in:
parent
068c5851ef
commit
e16bab8dd9
@ -25,6 +25,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "FX.h"
|
#include "FX.h"
|
||||||
|
#include "tv_colors.h"
|
||||||
|
|
||||||
#define IBN 5100
|
#define IBN 5100
|
||||||
#define PALETTE_SOLID_WRAP (paletteBlend == 1 || paletteBlend == 3)
|
#define PALETTE_SOLID_WRAP (paletteBlend == 1 || paletteBlend == 3)
|
||||||
@ -3753,3 +3754,95 @@ uint16_t WS2812FX::mode_blends(void) {
|
|||||||
|
|
||||||
return FRAMETIME;
|
return FRAMETIME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct TvSim {
|
||||||
|
uint32_t totalTime = 0;
|
||||||
|
uint32_t fadeTime = 0;
|
||||||
|
uint32_t startTime = 0;
|
||||||
|
uint32_t elapsed = 0;
|
||||||
|
uint32_t pixelNum = 0;
|
||||||
|
uint16_t pr = 0; // Prev R, G, B
|
||||||
|
uint16_t pg = 0;
|
||||||
|
uint16_t pb = 0;
|
||||||
|
} tvSim;
|
||||||
|
|
||||||
|
#define numTVPixels (sizeof(tv_colors) / 2) // 2 bytes per Pixel (5/6/5)
|
||||||
|
|
||||||
|
/*
|
||||||
|
TV Simulator
|
||||||
|
Modified and adapted to WLED by Def3nder, based on "Fake TV Light for Engineers" by Phillip Burgess https://learn.adafruit.com/fake-tv-light-for-engineers/arduino-sketch
|
||||||
|
*/
|
||||||
|
uint16_t WS2812FX::mode_tv_simulator(void) {
|
||||||
|
#ifdef WLED_DISABLE_FX_HIGH_FLASH_USE
|
||||||
|
return mode_static();
|
||||||
|
#else
|
||||||
|
uint16_t nr, ng, nb, r, g, b, i;
|
||||||
|
uint8_t hi, lo, r8, g8, b8;
|
||||||
|
|
||||||
|
if (!SEGENV.allocateData(sizeof(tvSim))) return mode_static(); //allocation failed
|
||||||
|
TvSim* tvSimulator = reinterpret_cast<TvSim*>(SEGENV.data);
|
||||||
|
|
||||||
|
// initialize start of the TV-Colors
|
||||||
|
if (SEGENV.call == 0) {
|
||||||
|
tvSimulator->pixelNum = ((uint8_t)random(18)) * numTVPixels / 18; // Begin at random movie (18 in total)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read next 16-bit (5/6/5) color
|
||||||
|
hi = pgm_read_byte(&tv_colors[tvSimulator->pixelNum * 2 ]);
|
||||||
|
lo = pgm_read_byte(&tv_colors[tvSimulator->pixelNum * 2 + 1]);
|
||||||
|
|
||||||
|
// Expand to 24-bit (8/8/8)
|
||||||
|
r8 = (hi & 0xF8) | (hi >> 5);
|
||||||
|
g8 = ((hi << 5) & 0xff) | ((lo & 0xE0) >> 3) | ((hi & 0x06) >> 1);
|
||||||
|
b8 = ((lo << 3) & 0xff) | ((lo & 0x1F) >> 2);
|
||||||
|
|
||||||
|
// Apply gamma correction, further expand to 16/16/16
|
||||||
|
nr = (uint8_t)gamma8(r8) * 257; // New R/G/B
|
||||||
|
ng = (uint8_t)gamma8(g8) * 257;
|
||||||
|
nb = (uint8_t)gamma8(b8) * 257;
|
||||||
|
|
||||||
|
if (SEGENV.aux0 == 0) { // initialize next iteration
|
||||||
|
SEGENV.aux0 = 1;
|
||||||
|
|
||||||
|
// increase color-index for next loop
|
||||||
|
tvSimulator->pixelNum++;
|
||||||
|
if (tvSimulator->pixelNum >= numTVPixels) tvSimulator->pixelNum = 0;
|
||||||
|
|
||||||
|
// randomize total duration and fade duration for the actual color
|
||||||
|
tvSimulator->totalTime = random(250, 2500); // Semi-random pixel-to-pixel time
|
||||||
|
tvSimulator->fadeTime = random(0, tvSimulator->totalTime); // Pixel-to-pixel transition time
|
||||||
|
if (random(10) < 3) tvSimulator->fadeTime = 0; // Force scene cut 30% of time
|
||||||
|
|
||||||
|
tvSimulator->startTime = millis();
|
||||||
|
} // end of initialization
|
||||||
|
|
||||||
|
// how much time is elapsed ?
|
||||||
|
tvSimulator->elapsed = millis() - tvSimulator->startTime;
|
||||||
|
|
||||||
|
// fade from prev volor to next color
|
||||||
|
if (tvSimulator->elapsed < tvSimulator->fadeTime) {
|
||||||
|
r = map(tvSimulator->elapsed, 0, tvSimulator->fadeTime, tvSimulator->pr, nr);
|
||||||
|
g = map(tvSimulator->elapsed, 0, tvSimulator->fadeTime, tvSimulator->pg, ng);
|
||||||
|
b = map(tvSimulator->elapsed, 0, tvSimulator->fadeTime, tvSimulator->pb, nb);
|
||||||
|
} else { // Avoid divide-by-zero in map()
|
||||||
|
r = nr;
|
||||||
|
g = ng;
|
||||||
|
b = nb;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set strip color
|
||||||
|
for (i = 0; i < SEGLEN; i++) {
|
||||||
|
setPixelColor(i, r >> 8, g >> 8, b >> 8); // Quantize to 8-bit
|
||||||
|
}
|
||||||
|
|
||||||
|
// if total duration has passed, remember last color and restart the loop
|
||||||
|
if ( tvSimulator->elapsed >= tvSimulator->totalTime) {
|
||||||
|
tvSimulator->pr = nr; // Prev RGB = new RGB
|
||||||
|
tvSimulator->pg = ng;
|
||||||
|
tvSimulator->pb = nb;
|
||||||
|
SEGENV.aux0 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FRAMETIME;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
12
wled00/FX.h
12
wled00/FX.h
@ -52,6 +52,9 @@
|
|||||||
#define MAX(a,b) ((a)>(b)?(a):(b))
|
#define MAX(a,b) ((a)>(b)?(a):(b))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Disable effects with high flash memory usage (currently TV simulator) - saves 18.5kB */
|
||||||
|
//#define WLED_DISABLE_FX_HIGH_FLASH_USE
|
||||||
|
|
||||||
/* Not used in all effects yet */
|
/* Not used in all effects yet */
|
||||||
#define WLED_FPS 42
|
#define WLED_FPS 42
|
||||||
#define FRAMETIME (1000/WLED_FPS)
|
#define FRAMETIME (1000/WLED_FPS)
|
||||||
@ -116,7 +119,7 @@
|
|||||||
#define IS_REVERSE ((SEGMENT.options & REVERSE ) == REVERSE )
|
#define IS_REVERSE ((SEGMENT.options & REVERSE ) == REVERSE )
|
||||||
#define IS_SELECTED ((SEGMENT.options & SELECTED ) == SELECTED )
|
#define IS_SELECTED ((SEGMENT.options & SELECTED ) == SELECTED )
|
||||||
|
|
||||||
#define MODE_COUNT 116
|
#define MODE_COUNT 117
|
||||||
|
|
||||||
#define FX_MODE_STATIC 0
|
#define FX_MODE_STATIC 0
|
||||||
#define FX_MODE_BLINK 1
|
#define FX_MODE_BLINK 1
|
||||||
@ -234,6 +237,7 @@
|
|||||||
#define FX_MODE_WASHING_MACHINE 113
|
#define FX_MODE_WASHING_MACHINE 113
|
||||||
#define FX_MODE_CANDY_CANE 114
|
#define FX_MODE_CANDY_CANE 114
|
||||||
#define FX_MODE_BLENDS 115
|
#define FX_MODE_BLENDS 115
|
||||||
|
#define FX_MODE_TV_SIMULATOR 116
|
||||||
|
|
||||||
class WS2812FX {
|
class WS2812FX {
|
||||||
typedef uint16_t (WS2812FX::*mode_ptr)(void);
|
typedef uint16_t (WS2812FX::*mode_ptr)(void);
|
||||||
@ -463,6 +467,7 @@ class WS2812FX {
|
|||||||
_mode[FX_MODE_WASHING_MACHINE] = &WS2812FX::mode_washing_machine;
|
_mode[FX_MODE_WASHING_MACHINE] = &WS2812FX::mode_washing_machine;
|
||||||
_mode[FX_MODE_CANDY_CANE] = &WS2812FX::mode_candy_cane;
|
_mode[FX_MODE_CANDY_CANE] = &WS2812FX::mode_candy_cane;
|
||||||
_mode[FX_MODE_BLENDS] = &WS2812FX::mode_blends;
|
_mode[FX_MODE_BLENDS] = &WS2812FX::mode_blends;
|
||||||
|
_mode[FX_MODE_TV_SIMULATOR] = &WS2812FX::mode_tv_simulator;
|
||||||
|
|
||||||
_brightness = DEFAULT_BRIGHTNESS;
|
_brightness = DEFAULT_BRIGHTNESS;
|
||||||
currentPalette = CRGBPalette16(CRGB::Black);
|
currentPalette = CRGBPalette16(CRGB::Black);
|
||||||
@ -673,7 +678,8 @@ class WS2812FX {
|
|||||||
mode_dancing_shadows(void),
|
mode_dancing_shadows(void),
|
||||||
mode_washing_machine(void),
|
mode_washing_machine(void),
|
||||||
mode_candy_cane(void),
|
mode_candy_cane(void),
|
||||||
mode_blends(void);
|
mode_blends(void),
|
||||||
|
mode_tv_simulator(void);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NeoPixelWrapper *bus;
|
NeoPixelWrapper *bus;
|
||||||
@ -761,7 +767,7 @@ const char JSON_mode_names[] PROGMEM = R"=====([
|
|||||||
"Twinklefox","Twinklecat","Halloween Eyes","Solid Pattern","Solid Pattern Tri","Spots","Spots Fade","Glitter","Candle","Fireworks Starburst",
|
"Twinklefox","Twinklecat","Halloween Eyes","Solid Pattern","Solid Pattern Tri","Spots","Spots Fade","Glitter","Candle","Fireworks Starburst",
|
||||||
"Fireworks 1D","Bouncing Balls","Sinelon","Sinelon Dual","Sinelon Rainbow","Popcorn","Drip","Plasma","Percent","Ripple Rainbow",
|
"Fireworks 1D","Bouncing Balls","Sinelon","Sinelon Dual","Sinelon Rainbow","Popcorn","Drip","Plasma","Percent","Ripple Rainbow",
|
||||||
"Heartbeat","Pacifica","Candle Multi", "Solid Glitter","Sunrise","Phased","Twinkleup","Noise Pal", "Sine","Phased Noise",
|
"Heartbeat","Pacifica","Candle Multi", "Solid Glitter","Sunrise","Phased","Twinkleup","Noise Pal", "Sine","Phased Noise",
|
||||||
"Flow","Chunchun","Dancing Shadows","Washing Machine","Candy Cane","Blends"
|
"Flow","Chunchun","Dancing Shadows","Washing Machine","Candy Cane","Blends","TV Simulator"
|
||||||
])=====";
|
])=====";
|
||||||
|
|
||||||
|
|
||||||
|
1506
wled00/tv_colors.h
Normal file
1506
wled00/tv_colors.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -22,10 +22,11 @@
|
|||||||
// You are required to disable over-the-air updates:
|
// You are required to disable over-the-air updates:
|
||||||
//#define WLED_DISABLE_OTA // saves 14kb
|
//#define WLED_DISABLE_OTA // saves 14kb
|
||||||
|
|
||||||
// You need to choose some of these features to disable:
|
// You can choose some of these features to disable:
|
||||||
//#define WLED_DISABLE_ALEXA // saves 11kb
|
//#define WLED_DISABLE_ALEXA // saves 11kb
|
||||||
//#define WLED_DISABLE_BLYNK // saves 6kb
|
//#define WLED_DISABLE_BLYNK // saves 6kb
|
||||||
//#define WLED_DISABLE_CRONIXIE // saves 3kb
|
//#define WLED_DISABLE_CRONIXIE // saves 3kb
|
||||||
|
//WLED_DISABLE_FX_HIGH_FLASH_USE (need to enable in PIO config or FX.h, saves 18kb)
|
||||||
//#define WLED_DISABLE_HUESYNC // saves 4kb
|
//#define WLED_DISABLE_HUESYNC // saves 4kb
|
||||||
//#define WLED_DISABLE_INFRARED // there is no pin left for this on ESP8266-01, saves 12kb
|
//#define WLED_DISABLE_INFRARED // there is no pin left for this on ESP8266-01, saves 12kb
|
||||||
#ifndef WLED_DISABLE_MQTT
|
#ifndef WLED_DISABLE_MQTT
|
||||||
|
Loading…
Reference in New Issue
Block a user