Merge branch 'master' of https://git.schle.nz/fabian/pitrix; added new effect tv_static.
Some checks reported errors
continuous-integration/drone/push Build encountered an error

This commit is contained in:
Fabian Schlenz 2019-10-10 06:50:09 +02:00
commit 359b7a7826
10 changed files with 95 additions and 65 deletions

View File

@ -9,7 +9,7 @@
class MatrixEffectColumn { class MatrixEffectColumn {
protected: protected:
Window* window; Window* window;
accum88 x, y; saccum78 x, y;
uint8_t length = 1; uint8_t length = 1;
uint8_t _direction = 2; uint8_t _direction = 2;
bool _random_direction = false; bool _random_direction = false;

View File

@ -0,0 +1,12 @@
#pragma once
#include "Effect.h"
class TvStaticEffect : public Effect {
private:
Window* _window = new Window(0, 0, LED_WIDTH, LED_HEIGHT-6);
public:
~TvStaticEffect();
void loop(uint16_t ms) override;
bool can_be_shown_with_clock() override;
String get_name() override { return "tv_static"; }
};

View File

@ -22,57 +22,61 @@ struct Settings {
uint16_t time = 300; uint16_t time = 300;
uint16_t random = 1; uint16_t random = 1;
} cycle ; } cycle ;
struct /* matrix */ { struct /* matrix */ {
uint16_t length_min = 4; uint16_t length_min = 4;
uint16_t length_max = 20; uint16_t length_max = 20;
uint16_t speed_min = 1; uint16_t speed_min = 3;
uint16_t speed_max = 10; uint16_t speed_max = 7;
} matrix; } matrix;
struct /* confetti */ { struct /* confetti */ {
uint16_t pixels_per_loop = 2; uint16_t pixels_per_loop = 2;
} confetti; } confetti;
struct /* dvd */ { struct /* dvd */ {
uint16_t width = 3; uint16_t width = 3;
uint16_t height = 2; uint16_t height = 2;
uint16_t speed = 50; uint16_t speed = 50;
} dvd; } dvd;
struct /* dynamic */ { struct /* dynamic */ {
uint16_t single_loop_time = 40; uint16_t single_loop_time = 40;
uint16_t multi_loop_time = 1400; uint16_t multi_loop_time = 1400;
uint16_t big_loop_time = 50; uint16_t big_loop_time = 50;
uint16_t big_size = 3; uint16_t big_size = 3;
} dynamic; } dynamic;
struct /* fire */ { struct /* fire */ {
uint16_t cooldown = 192; uint16_t cooldown = 192;
uint16_t spark_chance = 5; uint16_t spark_chance = 5;
} fire; } fire;
struct /* firework */ { struct /* firework */ {
uint16_t drag = 255; uint16_t drag = 255;
uint16_t bounce = 200; uint16_t bounce = 200;
uint16_t gravity = 10; uint16_t gravity = 10;
uint16_t sparks = 12; uint16_t sparks = 12;
} firework; } firework;
struct /* gol */ { struct /* gol */ {
uint16_t start_percentage = 90; uint16_t start_percentage = 90;
uint16_t blend_speed = 10; uint16_t blend_speed = 10;
uint16_t restart_after_steps = 100; uint16_t restart_after_steps = 100;
} gol; } gol;
struct /* sines */ { struct /* sines */ {
uint16_t count = 5; uint16_t count = 5;
} sines; } sines;
struct /* snake */ { struct /* snake */ {
uint16_t direction_change = 5; uint16_t direction_change = 5;
uint16_t slowdown = 2; uint16_t slowdown = 2;
} snake; } snake;
struct /* tv_static */ {
uint16_t black_bar_speed = 3500;
} tv_static;
} effects; } effects;
}; };

View File

@ -21,7 +21,7 @@ lib_deps =
ESPAsyncTCP ESPAsyncTCP
[env:ota] [env:ota]
upload_port = 10.10.2.78 upload_port = 10.10.2.80
upload_protocol = espota upload_protocol = espota
platform = espressif8266 platform = espressif8266
board = esp07 board = esp07

View File

@ -27,17 +27,10 @@ void BigClockEffect::_draw_seconds() {
for (int i=1; i<=seconds; i++) { for (int i=1; i<=seconds; i++) {
_draw_border_pixel(i, 0, (i%5==0) ? &_color_seconds_light : &_color_seconds_dark); _draw_border_pixel(i, 0, (i%5==0) ? &_color_seconds_light : &_color_seconds_dark);
} }
uint16_t millis = ntpClient.getEpochMillis() % 1000; uint16_t millis = ntpClient.getEpochMillis() % 1000;
/* uint8_t offset = 5 - (millis / 200);
// Enable this to have the next pixel move smoothly to its position uint8_t part = 255 - ((millis % 200) * 256 / 200);
if (millis > 0) {
uint8_t part = 60 - ((60 - seconds) * millis / 1000);
_draw_border_pixel(part, &_color_seconds);
}
*/
uint8_t offset = 5 - ((millis % 1000) / 200);
uint8_t part = scale8(millis % 200, 200);
uint8_t number_to_show = (60 - seconds - offset) / 5 + 1; uint8_t number_to_show = (60 - seconds - offset) / 5 + 1;
for(uint8_t i = 0; i<number_to_show; i++) { for(uint8_t i = 0; i<number_to_show; i++) {
uint8_t pos = seconds + offset + i*5; uint8_t pos = seconds + offset + i*5;
@ -46,26 +39,6 @@ void BigClockEffect::_draw_seconds() {
} }
void BigClockEffect::_draw_border_pixel(uint8_t i, uint8_t part, CRGB* color) { void BigClockEffect::_draw_border_pixel(uint8_t i, uint8_t part, CRGB* color) {
/*uint8_t x, y;
if (i<=8) {
x = 7 + i;
y = 0;
} else if (i<=23) {
x = 15;
y = i - 8;
} else if (i<= 38) {
x = 15 - i + 23;
y = 15;
} else if (i <= 53) {
x = 0;
y = 15 - i + 38;
} else if (i <= 60) {
x = i - 53;
y = 0;
} else {
return;
}
window->setPixel(x, y, color);*/
accum88 x, y; accum88 x, y;
if (i<=8) { if (i<=8) {
x = ((7+i)<<8) + part; x = ((7+i)<<8) + part;

View File

@ -47,7 +47,7 @@ void MatrixEffectColumn::advance(uint16_t ms) {
switch(_direction) { switch(_direction) {
case DIR_NORTH: case DIR_NORTH:
y-=speed * ms; y-=speed * ms;
if ((y>>8) > window->height && (y>>8) + length > window->height) running=false; if ((y>>8) + length < 0) running=false;
break; break;
case DIR_EAST: case DIR_EAST:
x+=speed * ms; x+=speed * ms;
@ -59,7 +59,7 @@ void MatrixEffectColumn::advance(uint16_t ms) {
break; break;
case DIR_WEST: case DIR_WEST:
x-=speed * ms; x-=speed * ms;
if ((x>>8) > window->width && (y>>8) + length > window->width) running=false; if ((x>>8) + length < 0) running=false;
break; break;
} }
} }

27
src/effect_tv_static.cpp Normal file
View File

@ -0,0 +1,27 @@
#include "effect_tv_static.h"
void TvStaticEffect::loop(uint16_t ms) {
uint8_t dark_position = (millis() % settings.effects.tv_static.black_bar_speed) * _window->width / settings.effects.tv_static.black_bar_speed;
for (uint8_t y=0; y<_window->height; y++) {
uint8_t row_dark_position = (dark_position + y/3) % _window->width;
for (uint8_t x=0; x<_window->width; x++) {
uint8_t brightness = random8();
uint8_t darkening = 0;
uint8_t distance = x - row_dark_position;
if (distance == 0) darkening = random8(192, 255);
else if (distance == 1) darkening = random8(128, 255);
else if (distance == 2) darkening = random8(92, 192);
else if (distance == 3) darkening = random8(32, 128);
if (darkening > brightness) brightness = 0;
else brightness -= darkening;
CRGB color(brightness, brightness, brightness);
_window->setPixel(x, y, &color);
}
}
}
bool TvStaticEffect::can_be_shown_with_clock() { return true; }
TvStaticEffect::~TvStaticEffect() {
delete _window;
}

View File

@ -22,6 +22,7 @@
#include "effect_sines.h" #include "effect_sines.h"
#include "effect_marquee.h" #include "effect_marquee.h"
#include "effect_blur2d.h" #include "effect_blur2d.h"
#include "effect_tv_static.h"
Effect* current_effect; Effect* current_effect;
@ -52,9 +53,10 @@ const EffectEntry effects[] = {
/* 21 */ {"sines", true, [](){ return new SinesEffect(); }}, /* 21 */ {"sines", true, [](){ return new SinesEffect(); }},
/* 22 */ {"blur2d", true, [](){ return new Blur2DEffect(); }}, /* 22 */ {"blur2d", true, [](){ return new Blur2DEffect(); }},
/* 23 */ {"marquee", 0, [](){ return new MarqueeEffect(); }}, /* 23 */ {"marquee", 0, [](){ return new MarqueeEffect(); }},
/* 24 */ {"night_clock", false, [](){ return new NightClockEffect(); }} /* 24 */ {"night_clock", false, [](){ return new NightClockEffect(); }},
/* 25 */ {"tv_static", false, [](){ return new TvStaticEffect(); }},
}; };
const uint8_t effects_size = 25; const uint8_t effects_size = 26;
Effect* select_effect(const char* name) { Effect* select_effect(const char* name) {

View File

@ -18,9 +18,9 @@ File upload_file;
void http_server_handle_file_upload() { void http_server_handle_file_upload() {
if (http_server.uri() != "/upload") return; if (http_server.uri() != "/upload") return;
HTTPUpload upload = http_server.upload(); HTTPUpload upload = http_server.upload();
if (upload.status == UPLOAD_FILE_START) { if (upload.status == UPLOAD_FILE_START) {
String filename = upload.filename; String filename = upload.filename;
if (!filename.startsWith("/")) filename = "/" + filename; if (!filename.startsWith("/")) filename = "/" + filename;
@ -42,7 +42,7 @@ void http_server_setup() {
PGM_P text_plain = PSTR("text/plain"); PGM_P text_plain = PSTR("text/plain");
http_server.on("/", HTTP_GET, [&](){ http_server.on("/", HTTP_GET, [&](){
LOGln("HTTP * GET /"); LOGln("HTTP * GET /");
String message = "<html><head><title>Pitrix</title></head><body><h1>Pitrix</h1><a href='/settings'>Settings</a><p>Known animations:</p>"; String message = "<html><head><title>Pitrix</title></head><body><h1>Pitrix</h1><p><a href='/settings'>Settings</a></p><p><a href='/effects'>Effect</a></p><p>Known animations:</p>";
if (!SPIFFS.begin()) { if (!SPIFFS.begin()) {
message += "<strong>No SPIFFS file system found.</strong>"; message += "<strong>No SPIFFS file system found.</strong>";
} else { } else {
@ -116,7 +116,7 @@ void http_server_setup() {
} }
String name = http_server.arg("key"); String name = http_server.arg("key");
uint16_t value = http_server.arg("value").toInt(); uint16_t value = http_server.arg("value").toInt();
if (change_setting(name.c_str(), value)) { if (change_setting(name.c_str(), value)) {
if (http_server.hasArg("redir")) { if (http_server.hasArg("redir")) {
http_server.sendHeader("Location", "/settings"); http_server.sendHeader("Location", "/settings");
@ -150,6 +150,16 @@ void http_server_setup() {
} }
http_server.send(500, "text/plain", "Could not read settings."); http_server.send(500, "text/plain", "Could not read settings.");
}); });
http_server.on("/effects", HTTP_GET, [&]() {
String message = "<html><head><title>Pitrix effects</title></head><body><h1>Pitrix settings</h1><a href='/'>Back to main page</a><table>";
for (int i=0; i<effects_size; i++) {
message += "<tr><td>";
message += effects[i].name;
message += "</td></tr>";
}
message += "</table></body></html>";
http_server.send(200, "text/html", message);
});
http_server.on("/delete", HTTP_GET, [&]() { http_server.on("/delete", HTTP_GET, [&]() {
LOGln("HTTP * GET /delete"); LOGln("HTTP * GET /delete");
if (http_server.args()==0) { if (http_server.args()==0) {
@ -216,7 +226,7 @@ void http_server_setup() {
} }
}); });
http_server.begin(); http_server.begin();
MDNS.addService("_http", "_tcp", 80); MDNS.addService("_http", "_tcp", 80);
} }

View File

@ -6,44 +6,46 @@ Settings settings;
Setting all_settings[] = { Setting all_settings[] = {
{"fps", &settings.fps, TYPE_UINT8}, {"fps", &settings.fps, TYPE_UINT8},
{"effects.confetti.pixels_per_loop", &settings.effects.confetti.pixels_per_loop, TYPE_UINT8}, {"effects.confetti.pixels_per_loop", &settings.effects.confetti.pixels_per_loop, TYPE_UINT8},
{"effects.cycle.random", &settings.effects.cycle.random, TYPE_BOOL}, {"effects.cycle.random", &settings.effects.cycle.random, TYPE_BOOL},
{"effects.cycle.time", &settings.effects.cycle.time, TYPE_UINT16}, {"effects.cycle.time", &settings.effects.cycle.time, TYPE_UINT16},
{"effects.dvd.width", &settings.effects.dvd.width, TYPE_UINT8}, {"effects.dvd.width", &settings.effects.dvd.width, TYPE_UINT8},
{"effects.dvd.height", &settings.effects.dvd.height, TYPE_UINT8}, {"effects.dvd.height", &settings.effects.dvd.height, TYPE_UINT8},
{"effects.dvd.speed", &settings.effects.dvd.speed, TYPE_UINT8}, {"effects.dvd.speed", &settings.effects.dvd.speed, TYPE_UINT8},
{"effects.dynamic.single_loop_time", &settings.effects.dynamic.single_loop_time, TYPE_UINT16}, {"effects.dynamic.single_loop_time", &settings.effects.dynamic.single_loop_time, TYPE_UINT16},
{"effects.dynamic.multi_loop_time", &settings.effects.dynamic.multi_loop_time, TYPE_UINT16}, {"effects.dynamic.multi_loop_time", &settings.effects.dynamic.multi_loop_time, TYPE_UINT16},
{"effects.dynamic.big_loop_time", &settings.effects.dynamic.big_loop_time, TYPE_UINT16}, {"effects.dynamic.big_loop_time", &settings.effects.dynamic.big_loop_time, TYPE_UINT16},
{"effects.dynamic.big_size", &settings.effects.dynamic.big_size, TYPE_UINT8}, {"effects.dynamic.big_size", &settings.effects.dynamic.big_size, TYPE_UINT8},
{"effects.fire.cooldown", &settings.effects.fire.cooldown, TYPE_UINT8}, {"effects.fire.cooldown", &settings.effects.fire.cooldown, TYPE_UINT8},
{"effects.fire.spark_chance", &settings.effects.fire.spark_chance, TYPE_UINT8}, {"effects.fire.spark_chance", &settings.effects.fire.spark_chance, TYPE_UINT8},
{"effects.firework.drag", &settings.effects.firework.drag, TYPE_UINT8}, {"effects.firework.drag", &settings.effects.firework.drag, TYPE_UINT8},
{"effects.firework.bounce", &settings.effects.firework.bounce, TYPE_UINT8}, {"effects.firework.bounce", &settings.effects.firework.bounce, TYPE_UINT8},
{"effects.firework.gravity", &settings.effects.firework.gravity, TYPE_UINT8}, {"effects.firework.gravity", &settings.effects.firework.gravity, TYPE_UINT8},
{"effects.firework.sparks", &settings.effects.firework.sparks, TYPE_UINT8}, {"effects.firework.sparks", &settings.effects.firework.sparks, TYPE_UINT8},
{"effects.gol.start_percentage", &settings.effects.gol.start_percentage, TYPE_UINT8}, {"effects.gol.start_percentage", &settings.effects.gol.start_percentage, TYPE_UINT8},
{"effects.gol.blend_speed", &settings.effects.gol.blend_speed, TYPE_UINT8}, {"effects.gol.blend_speed", &settings.effects.gol.blend_speed, TYPE_UINT8},
{"effects.gol.restart_after_steps", &settings.effects.gol.restart_after_steps, TYPE_UINT8}, {"effects.gol.restart_after_steps", &settings.effects.gol.restart_after_steps, TYPE_UINT8},
{"effects.matrix.length_min", &settings.effects.matrix.length_min, TYPE_UINT8}, {"effects.matrix.length_min", &settings.effects.matrix.length_min, TYPE_UINT8},
{"effects.matrix.length_max", &settings.effects.matrix.length_max, TYPE_UINT8}, {"effects.matrix.length_max", &settings.effects.matrix.length_max, TYPE_UINT8},
{"effects.matrix.speed_min", &settings.effects.matrix.speed_min, TYPE_UINT8}, {"effects.matrix.speed_min", &settings.effects.matrix.speed_min, TYPE_UINT8},
{"effects.matrix.speed_max", &settings.effects.matrix.speed_max, TYPE_UINT8}, {"effects.matrix.speed_max", &settings.effects.matrix.speed_max, TYPE_UINT8},
{"effects.sines.count", &settings.effects.sines.count, TYPE_UINT8}, {"effects.sines.count", &settings.effects.sines.count, TYPE_UINT8},
{"effects.snake.direction_change", &settings.effects.snake.direction_change, TYPE_UINT8},
{"effects.snake.direction_change", &settings.effects.snake.direction_change, TYPE_UINT8} {"effects.tv_static.black_bar_speed", &settings.effects.tv_static.black_bar_speed, TYPE_UINT16},
}; };
const uint8_t all_settings_size = 25; const uint8_t all_settings_size = 26;
bool change_setting(const char* key, uint16_t new_value) { bool change_setting(const char* key, uint16_t new_value) {
LOGln("Settings * Setting %s to new value %d.", key, new_value); LOGln("Settings * Setting %s to new value %d.", key, new_value);
@ -58,7 +60,7 @@ bool change_setting(const char* key, uint16_t new_value) {
LOGln("Settings * No setting matching the name %s found.", key); LOGln("Settings * No setting matching the name %s found.", key);
return false; return false;
} }
// Check data size // Check data size
if (s->type == TYPE_BOOL && new_value > 1) { if (s->type == TYPE_BOOL && new_value > 1) {
LOGln("Settings * Data type of %s is boolean, but new value is > 1.", key); LOGln("Settings * Data type of %s is boolean, but new value is > 1.", key);
@ -68,7 +70,7 @@ bool change_setting(const char* key, uint16_t new_value) {
LOGln("Settings * Data type of %s is uint8_t, but new value is > 0xFF.", key); LOGln("Settings * Data type of %s is uint8_t, but new value is > 0xFF.", key);
return false; return false;
} }
*(s->value) = new_value; *(s->value) = new_value;
return true; return true;
} }