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:
Def3nder 2020-12-22 13:15:57 +01:00 committed by GitHub
parent 068c5851ef
commit e16bab8dd9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 1611 additions and 5 deletions

View File

@ -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
}

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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