Compare commits

..

5 Commits

14 changed files with 194 additions and 29 deletions

View File

@ -7,11 +7,12 @@ class Window {
public:
const uint8_t x, y;
const uint8_t width, height;
uint16_t count;
static Window* getFullWindow();
Window(): Window(0, 0, LED_WIDTH, LED_HEIGHT) {};
Window(uint8_t x, uint8_t y) : Window(x, y, LED_WIDTH-x, LED_HEIGHT-y) {};
Window(uint8_t x, uint8_t y, uint8_t width, uint8_t height) : x(x), y(y), width(width), height(height) {};
Window(uint8_t x, uint8_t y, uint8_t width, uint8_t height) : x(x), y(y), width(width), height(height) { count = width*height; };
void clear();
void clear(CRGB* color);

View File

@ -39,3 +39,4 @@ extern AnimationData animation_couple_rain;
extern AnimationData animation_couple_snow;
extern AnimationData animation_heart;
extern AnimationData animation_weather_icons;
extern AnimationData animation_cake;

View File

@ -69,6 +69,8 @@
#define EFFECT_FIREWORK_BLUR 200
#define EFFECT_FIREWORK_FADEOUT_SPEED 5
#define EFFECT_GOL_START_PERCENTAGE 128
#define EFFECT_GOL_BLEND_SPEED 5
// Stop editing here

23
include/effect_gol.h Normal file
View File

@ -0,0 +1,23 @@
#pragma once
#include "Effect.h"
class GolEffect : public Effect {
private:
uint8_t *_data;
uint8_t *_old;
uint8_t _blend;
uint8_t _hue = 0;
uint8_t _old_hue = 0;
uint16_t _step;
void _advance();
void _draw();
void _initialize();
public:
GolEffect();
void start();
void stop();
void loop();
bool can_be_shown_with_clock();
};

View File

@ -40,3 +40,4 @@ typedef struct {
} Coords;
extern uint8_t baseHue;
extern char hostname[30];

View File

@ -11,6 +11,7 @@
[platformio]
lib_dir = lib
env_default = ota
lib_ldf_mode = chain+
[extra]
@ -28,6 +29,7 @@ platform = espressif8266
board = esp07
framework = arduino
lib_deps = ${extra.lib_deps}
lib_ldf_mode = chain+
[env:local]
upload_port = /dev/cu.wchusbserial1420
@ -35,6 +37,7 @@ platform = espressif8266
board = esp07
framework = arduino
lib_deps = ${extra.lib_deps}
lib_ldf_mode = chain+
[env:esp32]
platform = espressif32
@ -43,4 +46,5 @@ framework = arduino
lib_deps =
${extra.lib_deps}
ESP32WebServer
WiFiClient
FS
lib_ldf_mode = chain+

View File

@ -137,3 +137,29 @@ uint8_t animation_weather_icons_data[] PROGMEM = {
uint16_t animation_weather_icons_delays[] = {0};
uint16_t animation_weather_icons_offsets[] = {0,69,210,354,489,621,734,821,925,1061,1216,1359,1479,1627,1772,1841,1954,2060,2166,2308,2421,2551,2681,2763,2845,2927,3009,3093};
AnimationData animation_weather_icons = {&animation_weather_icons_colors[0], &animation_weather_icons_data[0], &animation_weather_icons_offsets[0], &animation_weather_icons_delays[0], false, 15, 27, 16, 16};
uint8_t animation_cake_colors[] PROGMEM = {91, 61, 0, 225, 225, 225, 184, 184, 113, 183, 123, 61, 255, 255, 142, 255, 174, 91, 255, 91, 91, 174, 174, 174, 255, 91, 174, 255, 40, 40, 255, 113, 40, 255, 40, 113, 174, 91, 255, 122, 82, 0, 255, 189, 122, 255, 255, 173};
uint8_t animation_cake_data[] PROGMEM = {
1,1,1,2,255,7,1,15,255,6,1,2,7,2,1,1,2,1,1,2,7,2,255,5,1,2,8,2,1,2,12,2,1,2,8,2,255,6,1,2,1,1,2,11,2,1,1,2,255,6,1,2,9,2,1,1,2,1,1,2,9,2,255,5,1,2,10,2,1,2,13,2,1,2,10,2,255,5,1,2,9,5,2,5,14,5,2,5,9,2,255,4,1,2,7,10,7,3,7,13,7,3,7,10,7,2,1,1,2,3,4,4,4,3,7,14,7,3,4,4,4,3,2,1,2,255,5,3,4,13,4,255,5,3,2,1,2,4,255,11,3,4,2,1,2,5,255,7,4,6,4,4,6,5,2,1,2,6,255,6,5,4,6,5,4,6,6,2,1,2,5,6,11,7,6,11,7,6,11,7,4,6,5,2,1,1,2,255,11,5,2,255,4,1,255,11,2,255,3,1,
255,11,0,2,255,23,0,11,0,0,0,7,0,0,0,11,255,11,0,12,255,200,0,
0,0,0,1,255,14,0,1,2,1,255,6,0,12,255,7,0,7,255,220,0,
0,0,0,2,255,7,0,1,255,6,0,2,0,2,255,5,0,1,2,1,255,10,0,5,0,0,0,7,255,11,0,7,255,200,0,
255,22,0,2,255,14,0,2,7,255,14,0,2,7,255,201,0,
255,39,0,2,1,255,12,0,1,2,255,201,0,
255,6,0,2,255,15,0,7,255,14,0,1,255,17,0,16,255,149,0,17,255,50,0,
255,6,0,1,255,15,0,1,255,15,0,2,5,2,0,0,2,255,11,0,5,255,149,0,6,255,50,0,
255,43,0,7,255,7,0,15,0,0,0,7,255,200,0
};
uint16_t animation_cake_delays[] = {80};
uint16_t animation_cake_offsets[] = {0,200,223,244,279,296,309,332,360,375};
AnimationData animation_cake = {
&animation_cake_colors[0],
&animation_cake_data[0],
&animation_cake_offsets[0],
&animation_cake_delays[0],
false, /* individual_frame_times */
16, /* color_count */
9, /* frames_count */
16, 16 /* width, height */
};

98
src/effect_gol.cpp Normal file
View File

@ -0,0 +1,98 @@
#include "effect_gol.h"
#include "my_fastled.h"
GolEffect::GolEffect() {
this->window = new Window(0, 0, LED_WIDTH, LED_HEIGHT-6);
}
bool GolEffect::can_be_shown_with_clock() { return true; }
void GolEffect::start() {
_data = new uint8_t[this->window->count];
_old = new uint8_t[this->window->count];
for(uint16_t i=0; i<this->window->count; i++) {
_old[i] = 0;
}
_initialize();
}
void GolEffect::_initialize() {
for(uint16_t i=0; i<this->window->count; i++) {
_data[i] = random8() < EFFECT_GOL_START_PERCENTAGE ? 1 : 0;
}
_old_hue = _hue;
_hue = random8();
_step = 0;
}
void GolEffect::stop() {
delete[] _data;
delete[] _old;
}
void GolEffect::loop() {
if (EFFECT_GOL_BLEND_SPEED + _blend > 255) {
_blend = 0;
_advance();
} else {
_blend += EFFECT_GOL_BLEND_SPEED;
}
_draw();
}
void GolEffect::_advance() {
_step++;
_old_hue = _hue;
if (_step >= EFFECT_GOL_RESTART_AFTER_STEPS) {
_initialize();
} else {
for(uint16_t i=0; i<this->window->count; i++) {
_old[i] = _data[i];
}
uint8_t w = this->window->width;
uint16_t changes = 0;
for(uint8_t x=0; x<this->window->width; x++) for(uint8_t y=0; y<this->window->height; y++) {
uint16_t index = y*w + x;
uint8_t count =
(x>0 && y>0 && _old[index - w - 1]) +
(y>0 && _old[index - w]) +
(x<this->window->width-1 && y>0 && _old[index - w + 1]) +
(x>0 && _old[index - 1]) +
(x<this->window->width-1 && _old[index + 1]) +
(x>0 && y<this->window->height-1 && _old[index + w - 1]) +
(y<this->window->height-1 && _old[index + w]) +
(x<this->window->width-1 && y<this->window->height-1 && _old[index + w + 1]);
if (_old[index]==0 && count==3) {
// birth
_data[index]=1;
changes++;
}
if (_old[index]>0) {
if (count<2 || count>3) {
//death
_data[index]=0;
changes++;
} else if (_data[index] < 255) {
//ageing
_data[index]++;
}
}
}
if (changes == 0) {
_initialize();
}
}
}
void GolEffect::_draw() {
for(uint16_t i=0; i<this->window->count; i++) {
CRGB o = _old[i]==0 ? CRGB::Black : (CRGB)CHSV(_old_hue, 180, 255);
CRGB n = _data[i]==0 ? CRGB::Black : (CRGB)CHSV(_hue, 180, 255);
CRGB result = nblend(o, n, _blend);
this->window->setPixelByIndex(i, &result);
}
}

View File

@ -16,6 +16,7 @@
#include "effect_snake.h"
#include "effect_fire.h"
#include "effect_firework.h"
#include "effect_gol.h"
SimpleList<EffectEntry>* effects;
SimpleList<Effect*>* cycle_effects;
@ -29,6 +30,7 @@ StaticEffect effect_off(CRGB(0x000000));
AnimationEffect effect_anim_koopa(&animation_koopa, new CRGB(0x000000), 0, 0);
AnimationEffect effect_anim_couple_rain(&animation_couple_rain, new CRGB(0x000000), -8, -16);
AnimationEffect effect_anim_heart(&animation_heart, new CRGB(0x000000), 0, 0);
AnimationEffect effect_anim_cake(&animation_cake, new CRGB(0x000000), 0, 0);
SingleDynamicEffect effect_single_dynamic;
MultiDynamicEffect effect_multi_dynamic;
MatrixEffect effect_matrix;
@ -38,6 +40,7 @@ ConfettiEffect effect_confetti;
SnakeEffect effect_snake;
FireEffect effect_fire;
FireworkEffect effect_firework;
GolEffect effect_gol;
Effect* current_effect;
@ -62,6 +65,8 @@ void setup_effects() {
effects->add((EffectEntry){"snake", (Effect *)&effect_snake});
effects->add((EffectEntry){"fire", (Effect *)&effect_fire});
effects->add((EffectEntry){"firework", (Effect *)&effect_firework});
effects->add((EffectEntry){"gol", (Effect *)&effect_gol});
effects->add((EffectEntry){"cake", (Effect *)&effect_anim_cake});
cycle_effects->add(&effect_sinematrix3);
cycle_effects->add(&effect_multi_dynamic);
@ -69,6 +74,7 @@ void setup_effects() {
cycle_effects->add(&effect_confetti);
cycle_effects->add(&effect_single_dynamic);
cycle_effects->add(&effect_snake);
cycle_effects->add(&effect_gol);
current_effect = &effect_cycle;
}

View File

@ -4,6 +4,8 @@
#include "http_server.h"
#include "effects.h"
#include "my_wifi.h"
#include "prototypes.h"
#if defined( ESP8266 )
ESP8266WebServer http_server(HTTP_SERVER_PORT);
@ -71,6 +73,8 @@ void http_server_setup() {
http_server.send_P(400, text_plain, PSTR("Unknown effect."));
});
http_server.begin();
MDNS.addService("_http", "_tcp", 80);
}
void http_server_loop() {

View File

@ -87,18 +87,8 @@ void mqtt_callback(char* original_topic, byte* pl, unsigned int length) {
}
boolean mqtt_connect() {
char client_id[30];
int chipid;
#if defined( ESP8266 )
chipid = ESP.getChipId();
#elif defined( ESP32 )
chipid = ESP.getEfuseMac() & 0xFFFFFF;
#else
#error Neither ESP32 nor ESP8266 set.
#endif
snprintf(client_id, 30, HOSTNAME, chipid);
LOG("MQTT * Connecting to MQTT server with client id "); LOGln(client_id);
if (mqtt_client.connect(client_id, MQTT_USER, MQTT_PASS, MQTT_TOPIC "status", 0, true, "OFFLINE", true)) {
LOG("MQTT * Connecting to MQTT server with client id "); LOGln(hostname);
if (mqtt_client.connect(hostname, MQTT_USER, MQTT_PASS, MQTT_TOPIC "status", 0, true, "OFFLINE", true)) {
LOGln("MQTT * Connected.");
mqtt_client.publish(MQTT_TOPIC "status", "ONLINE");
mqtt_client.subscribe(MQTT_TOPIC "+");

View File

@ -1,9 +1,9 @@
#include <ArduinoOTA.h>
#include "my_wifi.h"
#include <ArduinoOTA.h>
#include "config.h"
#include "prototypes.h"
void ota_setup() {
ArduinoOTA.onStart([]() {
@ -30,19 +30,9 @@ void ota_setup() {
else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
else if (error == OTA_END_ERROR) Serial.println("End Failed");
});
char client_id[30];
int chipid;
#if defined( ESP8266 )
chipid = ESP.getChipId();
#elif defined( ESP32 )
chipid = ESP.getEfuseMac() & 0xFFFFFF;
#else
#error Neither ESP32 nor ESP8266 set.
#endif
snprintf(client_id, 30, HOSTNAME, chipid);
LOG("OTA * Starting OTA with client_id "); LOGln(client_id);
ArduinoOTA.setHostname(client_id);
LOG("OTA * Starting OTA with client_id "); LOGln(hostname);
ArduinoOTA.setHostname(hostname);
ArduinoOTA.begin();
}

View File

@ -17,10 +17,20 @@ uint8_t starting_up = OTA_STARTUP_DELAY;
int loop_timeouts = 0;
long loop_started_at = 0;
uint8_t baseHue = 0; // defined as extern in prototypes.h
char hostname[30]; // defined as extern in prototypes.h
void setup() {
Serial.begin(74880);
LOGln("Core * Starting");
int chipid;
#if defined( ESP8266 )
chipid = ESP.getChipId();
#elif defined( ESP32 )
chipid = ESP.getEfuseMac() & 0xFFFFFF;
#endif
snprintf(hostname, 30, HOSTNAME, chipid);
setup_effects();
wifi_setup();
ntp_setup();

View File

@ -166,7 +166,16 @@ puts "uint16_t animation_#{name}_delays[] = {#{times.join(",")}};"
s=0
puts "uint16_t animation_#{name}_offsets[] = {#{(data.map{|d| t=s; s+=d.count; t} + [s]).join(",")}};"
puts "AnimationData animation_#{name} = {&animation_#{name}_colors[0], &animation_#{name}_data[0], &animation_#{name}_offsets[0], &animation_#{name}_delays[0], #{individual_frame_times}, #{colors.count-2}, #{frames_data.count}, #{total_x}, #{total_y}};"
puts "AnimationData animation_#{name} = {"
puts " &animation_#{name}_colors[0],"
puts " &animation_#{name}_data[0],"
puts " &animation_#{name}_offsets[0],"
puts " &animation_#{name}_delays[0],"
puts " #{individual_frame_times}, /* individual_frame_times */"
puts " #{colors.count-2}, /* color_count */"
puts " #{frames_data.count}, /* frames_count */"
puts " #{total_x}, #{total_y} /* width, height */"
puts "};"
puts
STDERR.puts
STDERR.puts "Space usage:"