Compare commits
11 Commits
521e5f735d
...
70ddba2cbc
Author | SHA1 | Date | |
---|---|---|---|
70ddba2cbc | |||
3f09d9adbf | |||
cfb25d6030 | |||
4762a852d8 | |||
8e2d2225cb | |||
65dd09ca0d | |||
f014fd7cae | |||
1707084299 | |||
402d7f5d75 | |||
d28dca0a4d | |||
439e2de17f |
@ -96,22 +96,18 @@
|
|||||||
Serial.println(buffer);\
|
Serial.println(buffer);\
|
||||||
} while (0);
|
} while (0);
|
||||||
#else
|
#else
|
||||||
#define LOG(msg, ...) do { \
|
#define LOG(x, ...) Serial.printf(x, ##__VA_ARGS__);
|
||||||
char buffer[128]; \
|
#define LOGln(x, ...) Serial.printf(x, ##__VA_ARGS__); Serial.println();
|
||||||
snprintf_P(buffer, 128, PSTR(msg), ##__VA_ARGS__);\
|
|
||||||
Serial.print(buffer);\
|
|
||||||
} while (0);
|
|
||||||
#define LOGln(msg, ...) do { \
|
|
||||||
char buffer[128]; \
|
|
||||||
snprintf_P(buffer, 128, PSTR(msg), ##__VA_ARGS__);\
|
|
||||||
Serial.println(buffer);\
|
|
||||||
} while (0);
|
|
||||||
#endif
|
#endif
|
||||||
|
#define DBG(msg, ...) Serial.printf(msg, ##__VA_ARGS__); Serial.println();
|
||||||
#else
|
#else
|
||||||
#define LOG(msg, ...) do {} while(0);
|
#define LOG(x) do {} while(0);
|
||||||
#define LOGln(msg, ...) do {} while(0);
|
#define LOGln(x) do {} while(0);
|
||||||
|
#define DBG(msg, ...) do {} while(0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if !defined( ESP8266 ) && !defined( ESP32 )
|
#if !defined( ESP8266 ) && !defined( ESP32 )
|
||||||
#error "Neither ESP8266 nor ESP32 are set. Maybe you are compiling this for another platform...?"
|
#error "Neither ESP8266 nor ESP32 are set. Maybe you are compiling this for another platform...?"
|
||||||
#endif
|
#endif
|
||||||
|
@ -11,12 +11,14 @@ private:
|
|||||||
const char* name;
|
const char* name;
|
||||||
uint16_t xOffset;
|
uint16_t xOffset;
|
||||||
uint16_t yOffset;
|
uint16_t yOffset;
|
||||||
|
unsigned long _last_blink_at;
|
||||||
|
uint16_t _blink_freq;
|
||||||
public:
|
public:
|
||||||
AnimationEffect(const char* name) : AnimationEffect(name, 0x000000, 0, 0) {}
|
AnimationEffect(const char* name, uint32_t bg_color=0x000000, int x=0, int y=0);
|
||||||
AnimationEffect(const char* name, uint32_t bg_color) : AnimationEffect(name, bg_color, 0, 0) {}
|
static AnimationEffect* Blinker(const char* name, uint16_t interval, uint32_t color, uint32_t background_color=0x000000);
|
||||||
AnimationEffect(const char* name, uint32_t bg_color, int x, int y);
|
|
||||||
~AnimationEffect();
|
~AnimationEffect();
|
||||||
AnimationEffect* setFgColor(uint32_t c);
|
AnimationEffect* setFgColor(uint32_t c);
|
||||||
|
AnimationEffect* setBlinkFrequency(uint16_t);
|
||||||
void loop(uint16_t ms);
|
void loop(uint16_t ms);
|
||||||
String get_name() override;
|
String get_name() override;
|
||||||
};
|
};
|
||||||
|
@ -3,17 +3,27 @@
|
|||||||
#include "Effect.h"
|
#include "Effect.h"
|
||||||
|
|
||||||
class BigClockEffect : public Effect {
|
class BigClockEffect : public Effect {
|
||||||
private:
|
protected:
|
||||||
CRGB _color_font = CRGB(0xAAAAAA);
|
CRGB _color_font = CRGB(0xAAAAAA);
|
||||||
CRGB _color_seconds_light = CRGB(0xFFFF00);
|
CRGB _color_seconds_light = CRGB(0xFFFF00);
|
||||||
CRGB _color_seconds_dark = CRGB(0xAA0000);
|
CRGB _color_seconds_dark = CRGB(0xAA0000);
|
||||||
CRGB _color_seconds_moving_light = CRGB(0x666600);
|
CRGB _color_seconds_moving_light = CRGB(0x666600);
|
||||||
CRGB _color_seconds_moving_dark = CRGB(0x660000);
|
CRGB _color_seconds_moving_dark = CRGB(0x660000);
|
||||||
|
|
||||||
void _draw_seconds(uint8_t seconds);
|
virtual CRGB _get_color_font() { return CRGB(0xAAAAAA); }
|
||||||
void _draw_border_pixel(accum88 pos, CRGB* color);
|
|
||||||
|
|
||||||
|
void _draw_seconds(uint8_t seconds);
|
||||||
|
virtual void _draw_border_pixel(accum88 pos, CRGB* color);
|
||||||
|
void _draw_colon(bool odd);
|
||||||
public:
|
public:
|
||||||
void loop(uint16_t ms);
|
virtual void loop(uint16_t ms);
|
||||||
String get_name() override { return "big_clock"; }
|
String get_name() override { return "big_clock"; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class NightClockEffect : public BigClockEffect {
|
||||||
|
private:
|
||||||
|
CRGB _color_font = CRGB(0x440000);
|
||||||
|
CRGB _color_colon = CRGB(0x000000);
|
||||||
|
void _draw_border_pixel(accum88 pos, CRGB* color) { };
|
||||||
|
CRGB _get_color_font() { return CRGB(0x440000); }
|
||||||
|
};
|
||||||
|
@ -16,10 +16,3 @@ public:
|
|||||||
void loop_with_invert(bool invert);
|
void loop_with_invert(bool invert);
|
||||||
void loop(boolean invert, CRGB fg_color, CRGB bg_color, uint8_t y);
|
void loop(boolean invert, CRGB fg_color, CRGB bg_color, uint8_t y);
|
||||||
};
|
};
|
||||||
|
|
||||||
class NightClockEffect : public ClockEffect {
|
|
||||||
public:
|
|
||||||
NightClockEffect();
|
|
||||||
~NightClockEffect();
|
|
||||||
void loop(uint16_t ms) override;
|
|
||||||
};
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
class LightspeedEffectStar {
|
class LightspeedEffectStar {
|
||||||
private:
|
private:
|
||||||
uint16_t _angle;
|
uint16_t _angle;
|
||||||
accum88 _start;
|
accum88 _distance;
|
||||||
uint16_t _speed;
|
uint16_t _speed;
|
||||||
uint16_t _target;
|
uint16_t _target;
|
||||||
uint8_t _saturation;
|
uint8_t _saturation;
|
||||||
|
@ -8,8 +8,12 @@ struct EffectEntry {
|
|||||||
const char* name;
|
const char* name;
|
||||||
bool use_in_cycle;
|
bool use_in_cycle;
|
||||||
std::function<Effect*()> create;
|
std::function<Effect*()> create;
|
||||||
|
#ifdef MQTT_REPORT_METRICS
|
||||||
|
int16_t heap_change_sum;
|
||||||
|
uint16_t run_count;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
extern const EffectEntry effects[];
|
extern EffectEntry effects[];
|
||||||
extern const uint8_t effects_size;
|
extern const uint8_t effects_size;
|
||||||
|
|
||||||
extern Effect* current_effect;
|
extern Effect* current_effect;
|
||||||
|
@ -17,8 +17,8 @@ void mqtt_setup();
|
|||||||
|
|
||||||
void mqtt_loop();
|
void mqtt_loop();
|
||||||
|
|
||||||
void mqtt_publish(const char* topic, int number);
|
void mqtt_publish(const char* topic, int number, bool retain=false);
|
||||||
void mqtt_publish(const char* topic, const char* message);
|
void mqtt_publish(const char* topic, const char* message, bool retain=false);
|
||||||
|
|
||||||
void mqtt_log(const char* message);
|
void mqtt_log(const char* message);
|
||||||
void mqtt_log(int number);
|
void mqtt_log(int number);
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
[platformio]
|
[platformio]
|
||||||
lib_dir = lib
|
lib_dir = lib
|
||||||
env_default = ota
|
default_envs = ota
|
||||||
|
|
||||||
[extra]
|
[extra]
|
||||||
lib_deps =
|
lib_deps =
|
||||||
@ -29,10 +29,12 @@ lib_ldf_mode = deep
|
|||||||
build_flags = -Wl,-Teagle.flash.2m512.ld
|
build_flags = -Wl,-Teagle.flash.2m512.ld
|
||||||
|
|
||||||
[env:local]
|
[env:local]
|
||||||
upload_port = /dev/cu.wchusbserial1420
|
upload_port = /dev/serial/by-id/usb-1a86_USB2.0-Serial-if00-port0
|
||||||
platform = espressif8266
|
platform = espressif8266
|
||||||
board = esp07
|
board = esp07
|
||||||
framework = arduino
|
framework = arduino
|
||||||
lib_deps = ${extra.lib_deps}
|
lib_deps = ${extra.lib_deps}
|
||||||
lib_ldf_mode = deep
|
lib_ldf_mode = deep
|
||||||
build_flags = -Wl,-Teagle.flash.2m512.ld
|
build_flags = -Wl,-Teagle.flash.2m512.ld
|
||||||
|
monitor_filters = time, esp8266_exception_decoder
|
||||||
|
build_type = debug
|
||||||
|
@ -84,16 +84,16 @@ bool Animation::_load_from_file(const char* filename) {
|
|||||||
// Now we can be sure to have the right amount of bytes available for reading
|
// Now we can be sure to have the right amount of bytes available for reading
|
||||||
|
|
||||||
_width = file.read();
|
_width = file.read();
|
||||||
LOGln("Animation * width: %d", _width);
|
DBG("Animation * width: %d", _width);
|
||||||
_height = file.read();
|
_height = file.read();
|
||||||
LOGln("Animation * height: %d", _height);
|
DBG("Animation * height: %d", _height);
|
||||||
|
|
||||||
_frame_count = file.read();
|
_frame_count = file.read();
|
||||||
LOGln("Animation * frame_count: %d", _frame_count);
|
DBG("Animation * frame_count: %d", _frame_count);
|
||||||
_color_count = file.read();
|
_color_count = file.read();
|
||||||
LOGln("Animation * color_count: %d", _color_count);
|
DBG("Animation * color_count: %d", _color_count);
|
||||||
|
|
||||||
LOGln("Animation * Loading colors...");
|
DBG("Animation * Loading colors...");
|
||||||
_colors = new CRGB*[_color_count];
|
_colors = new CRGB*[_color_count];
|
||||||
char* temp = new char[_color_count*3];
|
char* temp = new char[_color_count*3];
|
||||||
int bytes_read = file.readBytes(temp, _color_count*3);
|
int bytes_read = file.readBytes(temp, _color_count*3);
|
||||||
@ -102,36 +102,33 @@ bool Animation::_load_from_file(const char* filename) {
|
|||||||
_colors[i] = new CRGB(temp[i*3], temp[i*3+1], temp[i*3+2]);
|
_colors[i] = new CRGB(temp[i*3], temp[i*3+1], temp[i*3+2]);
|
||||||
}
|
}
|
||||||
delete [] temp;
|
delete [] temp;
|
||||||
LOGln("Animation * Color loading done.");
|
DBG("Animation * Color loading done.");
|
||||||
|
|
||||||
LOG("Animation * Loading frame times...");
|
DBG("Animation * Loading frame times...");
|
||||||
_frame_times = new uint16_t[_frame_count];
|
_frame_times = new uint16_t[_frame_count];
|
||||||
for (int i=0; i<_frame_count; i++) {
|
for (int i=0; i<_frame_count; i++) {
|
||||||
_frame_times[i] = (file.read() << 8) | file.read();
|
_frame_times[i] = (file.read() << 8) | file.read();
|
||||||
}
|
}
|
||||||
LOGln(" done.");
|
DBG(" done.");
|
||||||
|
|
||||||
LOGln("Animation * Loading frame lengths...");
|
DBG("Animation * Loading frame lengths...");
|
||||||
_frame_data_lengths = new uint16_t[_frame_count];
|
_frame_data_lengths = new uint16_t[_frame_count];
|
||||||
temp = new char[_frame_count*2];
|
temp = new char[_frame_count*2];
|
||||||
bytes_read = file.readBytes(temp, _frame_count*2);
|
bytes_read = file.readBytes(temp, _frame_count*2);
|
||||||
LOGln("Animation * Read %d bytes.", bytes_read);
|
DBG("Animation * Read %d bytes.", bytes_read);
|
||||||
for (int i=0; i<_frame_count; i++) {
|
for (int i=0; i<_frame_count; i++) {
|
||||||
//LOGln("Animation * Raw frame lengths: %d, %d", temp[i*2], temp[i*2+1]);
|
//LOGln("Animation * Raw frame lengths: %d, %d", temp[i*2], temp[i*2+1]);
|
||||||
_frame_data_lengths[i] = (temp[i*2]<<8) | temp[i*2+1];
|
_frame_data_lengths[i] = (temp[i*2]<<8) | temp[i*2+1];
|
||||||
}
|
}
|
||||||
delete [] temp;
|
delete [] temp;
|
||||||
LOGln("Animation * Frame length loading done.");
|
DBG("Animation * Frame length loading done.");
|
||||||
|
|
||||||
LOGln("Animation * Loading frame data...");
|
DBG("Animation * Loading frame data...");
|
||||||
_frame_data = new uint8_t*[_frame_count];
|
_frame_data = new uint8_t*[_frame_count];
|
||||||
for (int i=0; i<_frame_count; i++) {
|
for (int i=0; i<_frame_count; i++) {
|
||||||
uint16_t fl = _frame_data_lengths[i];
|
uint16_t fl = _frame_data_lengths[i];
|
||||||
LOGln("Animation * Loading frame %d with %d bytes...", i, fl);
|
DBG("Animation * Loading frame %d/%d with %d bytes...", i, _frame_count, fl);
|
||||||
_frame_data[i] = new uint8_t[fl];
|
_frame_data[i] = new uint8_t[fl];
|
||||||
/*for (int b=0; b<fl; b++) {
|
|
||||||
_frame_data[i][b] = file.read();
|
|
||||||
}*/
|
|
||||||
file.readBytes((char*)_frame_data[i], fl);
|
file.readBytes((char*)_frame_data[i], fl);
|
||||||
}
|
}
|
||||||
LOGln("Animation * Frame data loaded.");
|
LOGln("Animation * Frame data loaded.");
|
||||||
@ -208,27 +205,25 @@ void Animation::setSingleFrame(uint8_t frame) {
|
|||||||
Animation::~Animation() {
|
Animation::~Animation() {
|
||||||
for (int i=0; i<_color_count; i++) delete _colors[i];
|
for (int i=0; i<_color_count; i++) delete _colors[i];
|
||||||
|
|
||||||
LOGln("Animation * Deleting _colors...");
|
DBG("Animation * Deleting _colors...");
|
||||||
if (_colors) delete[] _colors;
|
if (_colors) delete[] _colors;
|
||||||
|
|
||||||
LOGln("Animation * Deleting fgColor...");
|
DBG("Animation * Deleting fgColor...");
|
||||||
if (fgColor != NULL) delete fgColor;
|
if (fgColor != NULL) delete fgColor;
|
||||||
|
|
||||||
LOGln("Animation * Deleting bgColor...");
|
DBG("Animation * Deleting bgColor...");
|
||||||
if (bgColor != NULL) delete bgColor;
|
if (bgColor != NULL) delete bgColor;
|
||||||
|
|
||||||
LOGln("Animation * Deleting _frame_data_lengths...");
|
DBG("Animation * Deleting _frame_data_lengths...");
|
||||||
if (_frame_data_lengths) delete[] _frame_data_lengths;
|
if (_frame_data_lengths) delete[] _frame_data_lengths;
|
||||||
|
|
||||||
LOGln("Animation * Deleting _frame_times...");
|
DBG("Animation * Deleting _frame_times...");
|
||||||
if (_frame_times) delete[] _frame_times;
|
if (_frame_times) delete[] _frame_times;
|
||||||
for (int i=0; i<_frame_count; i++) {
|
for (int i=0; i<_frame_count; i++) {
|
||||||
delete[] _frame_data[i];
|
delete[] _frame_data[i];
|
||||||
}
|
}
|
||||||
|
DBG("Animation * Deleting _frame_data...");
|
||||||
LOGln("Animation * Deleting _frame_data...");
|
|
||||||
if (_frame_data) delete[] _frame_data;
|
if (_frame_data) delete[] _frame_data;
|
||||||
|
|
||||||
LOGln("Animation * Deletion done.");
|
LOGln("Animation * Deletion done.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,6 +218,11 @@ void Window::lineWithAngle(uint8_t x, uint8_t y, uint16_t angle, uint8_t startdi
|
|||||||
y1 = (y<<8) + (startdist<<8) * sin16(angle) / 0x10000;
|
y1 = (y<<8) + (startdist<<8) * sin16(angle) / 0x10000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (length==0) {
|
||||||
|
setSubPixel(x1, y1, color);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
saccum78 x2 = (x<<8) + ((startdist + length)<<8) * cos16(angle) / 0x10000;
|
saccum78 x2 = (x<<8) + ((startdist + length)<<8) * cos16(angle) / 0x10000;
|
||||||
saccum78 y2 = (y<<8) + ((startdist + length)<<8) * sin16(angle) / 0x10000;
|
saccum78 y2 = (y<<8) + ((startdist + length)<<8) * sin16(angle) / 0x10000;
|
||||||
//LOGln("x1: %d.%03d, y1: %d.%03d, x2: %d.%03d, y2: %d.%03d", x1>>8, x1&0xFF, y1>>8, y1&0xFF, x2>>8, x2&0xFF, y2>>8, y2&0xFF);
|
//LOGln("x1: %d.%03d, y1: %d.%03d, x2: %d.%03d, y2: %d.%03d", x1>>8, x1&0xFF, y1>>8, y1&0xFF, x2>>8, x2&0xFF, y2>>8, y2&0xFF);
|
||||||
|
@ -9,6 +9,8 @@ AnimationEffect::AnimationEffect(const char* name, uint32_t bg, int x, int y) {
|
|||||||
this->animation = new Animation(name, window);
|
this->animation = new Animation(name, window);
|
||||||
this->animation->setBgColor(bg);
|
this->animation->setBgColor(bg);
|
||||||
this->animation->setOffsets(this->xOffset, this->yOffset);
|
this->animation->setOffsets(this->xOffset, this->yOffset);
|
||||||
|
|
||||||
|
_last_blink_at = millis();
|
||||||
}
|
}
|
||||||
|
|
||||||
AnimationEffect* AnimationEffect::setFgColor(uint32_t c) {
|
AnimationEffect* AnimationEffect::setFgColor(uint32_t c) {
|
||||||
@ -16,11 +18,23 @@ AnimationEffect* AnimationEffect::setFgColor(uint32_t c) {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AnimationEffect* AnimationEffect::setBlinkFrequency(uint16_t ms) {
|
||||||
|
_blink_freq = ms;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
AnimationEffect::~AnimationEffect() {
|
AnimationEffect::~AnimationEffect() {
|
||||||
delete this->animation;
|
delete this->animation;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnimationEffect::loop(uint16_t ms) {
|
void AnimationEffect::loop(uint16_t ms) {
|
||||||
|
if (_blink_freq > 0) {
|
||||||
|
unsigned long mil = millis();
|
||||||
|
if (mil < _last_blink_at || _last_blink_at + _blink_freq <= mil) {
|
||||||
|
this->animation->invert();
|
||||||
|
_last_blink_at = mil;
|
||||||
|
}
|
||||||
|
}
|
||||||
this->animation->drawFrame();
|
this->animation->drawFrame();
|
||||||
this->animation->advance();
|
this->animation->advance();
|
||||||
}
|
}
|
||||||
@ -30,3 +44,10 @@ String AnimationEffect::get_name() {
|
|||||||
s += this->name;
|
s += this->name;
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AnimationEffect* AnimationEffect::Blinker(const char* name, uint16_t interval, uint32_t color, uint32_t background_color) {
|
||||||
|
AnimationEffect* anim = new AnimationEffect(name, background_color);
|
||||||
|
anim->setFgColor(color);
|
||||||
|
anim->setBlinkFrequency(interval);
|
||||||
|
return anim;
|
||||||
|
}
|
||||||
|
@ -11,35 +11,43 @@ void BigClockEffect::loop(uint16_t ms) {
|
|||||||
time(&now);
|
time(&now);
|
||||||
localtime_r(&now, &timeinfo);
|
localtime_r(&now, &timeinfo);
|
||||||
uint8_t h = timeinfo.tm_hour;
|
uint8_t h = timeinfo.tm_hour;
|
||||||
window->drawChar(&font_numbers3x5_blocky, 6<<8, 2<<8, '0' + (h / 10), &_color_font);
|
CRGB color = _get_color_font();
|
||||||
window->drawChar(&font_numbers3x5_blocky, 11<<8, 2<<8, '0' + (h % 10), &_color_font);
|
window->drawChar(&font_numbers3x5_blocky, 6<<8, 2<<8, '0' + (h / 10), &color);
|
||||||
|
window->drawChar(&font_numbers3x5_blocky, 11<<8, 2<<8, '0' + (h % 10), &color);
|
||||||
|
|
||||||
uint8_t m = timeinfo.tm_min;
|
uint8_t m = timeinfo.tm_min;
|
||||||
window->drawChar(&font_numbers3x5_blocky, 6<<8, 9<<8, '0' + (m / 10), &_color_font);
|
window->drawChar(&font_numbers3x5_blocky, 6<<8, 9<<8, '0' + (m / 10), &color);
|
||||||
window->drawChar(&font_numbers3x5_blocky, 11<<8, 9<<8, '0' + (m % 10), &_color_font);
|
window->drawChar(&font_numbers3x5_blocky, 11<<8, 9<<8, '0' + (m % 10), &color);
|
||||||
|
|
||||||
uint8_t s = timeinfo.tm_sec;
|
uint8_t s = timeinfo.tm_sec;
|
||||||
if (s & 1) {
|
_draw_colon(s & 1);
|
||||||
window->setPixel(3, 10, &_color_font);
|
|
||||||
window->setPixel(3, 12, &_color_font);
|
|
||||||
}
|
|
||||||
|
|
||||||
_draw_seconds(timeinfo.tm_sec);
|
_draw_seconds(timeinfo.tm_sec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BigClockEffect::_draw_colon(bool odd) {
|
||||||
|
if (odd) {
|
||||||
|
CRGB color = _get_color_font();
|
||||||
|
window->setPixel(3, 10, &color);
|
||||||
|
window->setPixel(3, 12, &color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void BigClockEffect::_draw_seconds(uint8_t seconds) {
|
void BigClockEffect::_draw_seconds(uint8_t seconds) {
|
||||||
for (int i=1; i<=seconds; i++) {
|
for (int i=1; i<=seconds; i++) {
|
||||||
_draw_border_pixel(i<<8, (i%5==0) ? &_color_seconds_light : &_color_seconds_dark);
|
_draw_border_pixel(i<<8, (i%5==0) ? &_color_seconds_light : &_color_seconds_dark);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t mil = millis() % 1000;
|
/*timeval tv;
|
||||||
|
gettimeofday(&tv, nullptr);
|
||||||
|
uint16_t mil = (tv.tv_usec / 1000) % 1000;
|
||||||
accum88 pos = (seconds<<8) + ((settings.effects.big_clock.spacing-1)<<8) * (1000 - mil) / 1000 + (1<<8);
|
accum88 pos = (seconds<<8) + ((settings.effects.big_clock.spacing-1)<<8) * (1000 - mil) / 1000 + (1<<8);
|
||||||
uint8_t sec = seconds + 1;
|
uint8_t sec = seconds + 1;
|
||||||
while (pos < (60<<8)) {
|
while (pos < (60<<8)) {
|
||||||
_draw_border_pixel(pos, sec%5==0 ? &_color_seconds_moving_light : &_color_seconds_moving_dark);
|
_draw_border_pixel(pos, sec%5==0 ? &_color_seconds_moving_light : &_color_seconds_moving_dark);
|
||||||
pos += settings.effects.big_clock.spacing<<8;
|
pos += settings.effects.big_clock.spacing<<8;
|
||||||
sec++;
|
sec++;
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void BigClockEffect::_draw_border_pixel(accum88 i, CRGB* color) {
|
void BigClockEffect::_draw_border_pixel(accum88 i, CRGB* color) {
|
||||||
|
@ -4,18 +4,6 @@
|
|||||||
#include "fonts.h"
|
#include "fonts.h"
|
||||||
#include "ntp.h"
|
#include "ntp.h"
|
||||||
|
|
||||||
NightClockEffect::NightClockEffect() {
|
|
||||||
window = Window::getFullWindow();
|
|
||||||
}
|
|
||||||
|
|
||||||
void NightClockEffect::loop(uint16_t ms) {
|
|
||||||
uint16_t minutes = minutes16();
|
|
||||||
//uint8_t y = minutes % ((window->height - 5) * 2 - 2);
|
|
||||||
//if (y > window->height - 5) y = 2*window->height - 2*y;
|
|
||||||
uint8_t y = minutes % 10;
|
|
||||||
ClockEffect::loop(false, CRGB(0x200000), CRGB(0x000000), y);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClockEffect::loop(uint16_t ms) {
|
void ClockEffect::loop(uint16_t ms) {
|
||||||
loop_with_invert(false);
|
loop_with_invert(false);
|
||||||
}
|
}
|
||||||
@ -66,7 +54,3 @@ void ClockEffect::loop(boolean invert, CRGB fg_color, CRGB bg_color, uint8_t yPo
|
|||||||
ClockEffect::~ClockEffect() {
|
ClockEffect::~ClockEffect() {
|
||||||
delete window;
|
delete window;
|
||||||
}
|
}
|
||||||
|
|
||||||
NightClockEffect::~NightClockEffect() {
|
|
||||||
delete window;
|
|
||||||
}
|
|
@ -26,31 +26,46 @@ void CycleEffect::changeEffect() {
|
|||||||
LOGln("CycleEffect * Changing effect from #%d to #%d", effect_id, new_id);
|
LOGln("CycleEffect * Changing effect from #%d to #%d", effect_id, new_id);
|
||||||
delay(25);
|
delay(25);
|
||||||
|
|
||||||
if (effect) delete effect;
|
String old_effect_name = String("UNKNOWN");
|
||||||
|
if (effect) {
|
||||||
|
old_effect_name = effect->get_name();
|
||||||
|
delete effect;
|
||||||
|
}
|
||||||
|
|
||||||
int16_t diff;
|
int16_t diff = 0;
|
||||||
uint16_t old_heap = _heap_free;
|
uint16_t old_heap = _heap_free;
|
||||||
_heap_free = ESP.getFreeHeap();
|
_heap_free = ESP.getFreeHeap();
|
||||||
if (old_heap) {
|
if (old_heap) {
|
||||||
// diff positive = More heap used (baad)
|
// diff positive = More heap used (baad)
|
||||||
// diff negative = Less heap used (good-ish)
|
// diff negative = Less heap used (good-ish)
|
||||||
diff = old_heap - _heap_free;
|
diff = old_heap - _heap_free;
|
||||||
LOGln("CycleEffect * Heap usage: #%d,%d,%+d", effect_id, _heap_free, diff);
|
LOGln("CycleEffect * Heap usage: #%d,%s,%d,%+d", effect_id, old_effect_name.c_str(), _heap_free, diff);
|
||||||
}
|
}
|
||||||
|
|
||||||
delay(25);
|
delay(25);
|
||||||
LOGln("CycleEffect * Searching for new effect #%d", new_id);
|
LOGln("CycleEffect * Searching for new effect #%d", new_id);
|
||||||
uint8_t count = 0;
|
uint8_t count = 0;
|
||||||
|
EffectEntry* e = nullptr;
|
||||||
for (uint8_t i=0; i<effects_size; i++) {
|
for (uint8_t i=0; i<effects_size; i++) {
|
||||||
if (effects[i].use_in_cycle) {
|
if (effects[i].use_in_cycle) {
|
||||||
if (count == new_id) {
|
if (count == new_id) {
|
||||||
effect = effects[i].create();
|
e = &effects[i];
|
||||||
|
effect = e->create();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (effect) {
|
if (e) {
|
||||||
|
#ifdef MQTT_REPORT_METRICS
|
||||||
|
e->heap_change_sum += diff;
|
||||||
|
e->run_count++;
|
||||||
|
LOGln("CycleEffect * Last effect stats: name:%s, runs:%d, total_change:%d", old_effect_name.c_str(), e->run_count, e->heap_change_sum);
|
||||||
|
String topic = "metrics/effects/";
|
||||||
|
topic.concat(old_effect_name);
|
||||||
|
String message = String("runs:") + e->run_count + ", total_heap_change:" + e->heap_change_sum;
|
||||||
|
mqtt_publish(topic.c_str(), message.c_str(), true);
|
||||||
|
#endif
|
||||||
effect_id = new_id;
|
effect_id = new_id;
|
||||||
effectSince = millis();
|
effectSince = millis();
|
||||||
LOGln("CycleEffect * Effect %s found", effect->get_name().c_str());
|
LOGln("CycleEffect * Effect %s found", effect->get_name().c_str());
|
||||||
|
@ -40,11 +40,12 @@ boolean LightspeedEffect::can_be_shown_with_clock() { return true; };
|
|||||||
|
|
||||||
LightspeedEffectStar::LightspeedEffectStar() {
|
LightspeedEffectStar::LightspeedEffectStar() {
|
||||||
_init();
|
_init();
|
||||||
|
_distance = random16(10<<8);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LightspeedEffectStar::_init() {
|
void LightspeedEffectStar::_init() {
|
||||||
_angle = random16();
|
_angle = random16();
|
||||||
_start = 0;
|
_distance = 0;
|
||||||
_speed = random16(128, 2<<8);
|
_speed = random16(128, 2<<8);
|
||||||
_target = random16(25<<8, 35<<8);
|
_target = random16(25<<8, 35<<8);
|
||||||
_saturation = random8(100);
|
_saturation = random8(100);
|
||||||
@ -52,12 +53,14 @@ void LightspeedEffectStar::_init() {
|
|||||||
|
|
||||||
void LightspeedEffectStar::loop(Window* win) {
|
void LightspeedEffectStar::loop(Window* win) {
|
||||||
CRGB col = CHSV(192, _saturation, 255);
|
CRGB col = CHSV(192, _saturation, 255);
|
||||||
if (_start < (8<<8)) {
|
accum88 current_speed = _speed * beatsin16(0x100, 0, 65535) / 65535;
|
||||||
win->lineWithAngle(win->width/2, win->height/2, _angle, 0, _start>>8, &col);
|
uint8_t length = (current_speed>>6);
|
||||||
|
if (_distance < (length<<8)) {
|
||||||
|
win->lineWithAngle(win->width/2, win->height/2, _angle, 0, _distance>>8, &col);
|
||||||
} else {
|
} else {
|
||||||
win->lineWithAngle(win->width/2, win->height/2, _angle, (_start>>8) - 8, 8, &col);
|
win->lineWithAngle(win->width/2, win->height/2, _angle, (_distance>>8) - length, length, &col);
|
||||||
}
|
}
|
||||||
_start+=_speed;
|
_distance += current_speed;
|
||||||
//_angle+=8<<8;
|
//_angle+=8<<8;
|
||||||
if (_start > _target) _init();
|
if (_distance > _target) _init();
|
||||||
}
|
}
|
||||||
|
@ -31,11 +31,11 @@ ClockEffect effect_clock;
|
|||||||
TimerEffect effect_timer;
|
TimerEffect effect_timer;
|
||||||
|
|
||||||
// We're using 0 instead of false to get a better visual difference between true and false.
|
// We're using 0 instead of false to get a better visual difference between true and false.
|
||||||
const EffectEntry effects[] = {
|
EffectEntry effects[] = {
|
||||||
/* 0 */ {"sinematrix3", true, [](){ return new Sinematrix3Effect(); }},
|
/* 0 */ {"sinematrix3", true, [](){ return new Sinematrix3Effect(); }},
|
||||||
/* 1 */ {"big_clock", true, [](){ return new BigClockEffect(); }},
|
/* 1 */ {"big_clock", true, [](){ return new BigClockEffect(); }},
|
||||||
/* 2 */ {"clock", 0, [](){ return new ClockEffect(); }},
|
/* 2 */ {"clock", 0, [](){ return new ClockEffect(); }},
|
||||||
/* 3 */ {"bell", 0, [](){ return new BellEffect(); }},
|
/* 3 */ {"bell", 0, [](){ return AnimationEffect::Blinker("/bell.pia", 300, 0xFFFF00); }},
|
||||||
/* 4 */ {"off", 0, [](){ return new StaticEffect(0x000000); }},
|
/* 4 */ {"off", 0, [](){ return new StaticEffect(0x000000); }},
|
||||||
/* 5 */ {"single_dynamic", true, [](){ return new SingleDynamicEffect(); }},
|
/* 5 */ {"single_dynamic", true, [](){ return new SingleDynamicEffect(); }},
|
||||||
/* 6 */ {"multi_dynamic", true, [](){ return new MultiDynamicEffect(); }},
|
/* 6 */ {"multi_dynamic", true, [](){ return new MultiDynamicEffect(); }},
|
||||||
@ -61,8 +61,11 @@ const EffectEntry effects[] = {
|
|||||||
/* 26 */ {"sinematrix3_rainbow", true, [](){ return new Sinematrix3Effect(SINEMATRIX_COLOR_RAINBOW); }},
|
/* 26 */ {"sinematrix3_rainbow", true, [](){ return new Sinematrix3Effect(SINEMATRIX_COLOR_RAINBOW); }},
|
||||||
/* 27 */ {"sinematrix3_purplefly", true, [](){ return new Sinematrix3Effect(SINEMATRIX_COLOR_PURPLEFLY); }},
|
/* 27 */ {"sinematrix3_purplefly", true, [](){ return new Sinematrix3Effect(SINEMATRIX_COLOR_PURPLEFLY); }},
|
||||||
/* 28 */ {"lightspeed", true, [](){ return new LightspeedEffect(); }},
|
/* 28 */ {"lightspeed", true, [](){ return new LightspeedEffect(); }},
|
||||||
|
/* 29 */ {"koopa", 0, [](){ return new AnimationEffect("/koopa.pia"); }},
|
||||||
|
/* 30 */ {"cake", 0, [](){ return new AnimationEffect("/cake.pia"); }},
|
||||||
|
/* 31 */ {"kid", 0, [](){ return new AnimationEffect("/kid.pia"); }},
|
||||||
};
|
};
|
||||||
const uint8_t effects_size = 29;
|
const uint8_t effects_size = 32;
|
||||||
|
|
||||||
|
|
||||||
Effect* select_effect(const char* name) {
|
Effect* select_effect(const char* name) {
|
||||||
|
10
src/mqtt.cpp
10
src/mqtt.cpp
@ -23,7 +23,7 @@ void mqtt_callback(char* original_topic, byte* pl, unsigned int length) {
|
|||||||
pl[length] = '\0';
|
pl[length] = '\0';
|
||||||
String payload((char*)pl);
|
String payload((char*)pl);
|
||||||
String topic (original_topic);
|
String topic (original_topic);
|
||||||
if (topic.equals(MQTT_TOPIC "log") || topic.equals(MQTT_TOPIC "status") || topic.equals(MQTT_TOPIC "metrics")) {
|
if (topic.equals(MQTT_TOPIC "log") || topic.equals(MQTT_TOPIC "status") || topic.startsWith(MQTT_TOPIC "metrics")) {
|
||||||
// Return our own messages
|
// Return our own messages
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -133,16 +133,16 @@ void mqtt_loop() {
|
|||||||
|
|
||||||
String mqtt_log_str = String();
|
String mqtt_log_str = String();
|
||||||
|
|
||||||
void mqtt_publish(const char* topic, int number) {
|
void mqtt_publish(const char* topic, int number, bool retain) {
|
||||||
char b[32];
|
char b[32];
|
||||||
sprintf(b, "%d", number);
|
sprintf(b, "%d", number);
|
||||||
mqtt_publish(topic, b);
|
mqtt_publish(topic, b, retain);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mqtt_publish(const char* topic, const char* message) {
|
void mqtt_publish(const char* topic, const char* message, bool retain) {
|
||||||
char t[127];
|
char t[127];
|
||||||
sprintf(t, MQTT_TOPIC "%s", topic);
|
sprintf(t, MQTT_TOPIC "%s", topic);
|
||||||
mqtt_client.publish(t, message);
|
mqtt_client.publish(t, message, retain);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mqtt_log(const char* message) {
|
void mqtt_log(const char* message) {
|
||||||
|
@ -51,7 +51,16 @@ void setup() {
|
|||||||
#ifdef MQTT_ENABLE
|
#ifdef MQTT_ENABLE
|
||||||
mqtt_setup();
|
mqtt_setup();
|
||||||
#endif
|
#endif
|
||||||
SPIFFS.begin();
|
if (!SPIFFS.begin()) {
|
||||||
|
LOGln("Core * Could not open SPIFFS filesystem");
|
||||||
|
} else {
|
||||||
|
LOGln("Core * Files in SPIFFS filesystem:");
|
||||||
|
Dir d = SPIFFS.openDir("/");
|
||||||
|
while(d.next()) {
|
||||||
|
LOGln("Core * %s", d.fileName().c_str());
|
||||||
|
}
|
||||||
|
LOGln("Core * End of SPIFFS file listing.");
|
||||||
|
}
|
||||||
load_settings();
|
load_settings();
|
||||||
LOGln("Core * Setup complete");
|
LOGln("Core * Setup complete");
|
||||||
}
|
}
|
||||||
|
@ -16,9 +16,13 @@ namespace tests {
|
|||||||
for (int j=0; j<3; j++) {
|
for (int j=0; j<3; j++) {
|
||||||
int free_at_start = ESP.getFreeHeap();
|
int free_at_start = ESP.getFreeHeap();
|
||||||
effect = select_effect(i);
|
effect = select_effect(i);
|
||||||
effect->loop(1);
|
|
||||||
if (effect == NULL) return;
|
if (effect == NULL) return;
|
||||||
effect_name = effect->get_name();
|
effect_name = effect->get_name();
|
||||||
|
if (effect_name && !effect_name.equals("cycle")) {
|
||||||
|
LOGln("Testing effect %s...", effect_name.c_str());
|
||||||
|
delay(1);
|
||||||
|
effect->loop(1);
|
||||||
|
}
|
||||||
delete effect;
|
delete effect;
|
||||||
diffs[i] = ESP.getFreeHeap() - free_at_start;
|
diffs[i] = ESP.getFreeHeap() - free_at_start;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user