Effekte in einer Datei versammelt; Animation hinzugefügt.

This commit is contained in:
Fabian Schlenz 2019-05-22 06:52:41 +02:00
parent a88f7b5ec2
commit 24f6c7e798
11 changed files with 269 additions and 196 deletions

14
animations.h Normal file
View File

@ -0,0 +1,14 @@
typedef struct {
uint32_t *colors;
uint8_t *data;
uint16_t *offsets;
int color_count;
int frame_count;
int w;
int h;
} AnimationData;
uint32_t koopa_colors[] = {0x000000, 0x000000, 0xFF00FF, 0xB69A11, 0x303030, 0x8E0406, 0xFEFCFF, 0x03018A, 0x11EF12};
uint8_t koopa_data[] = {255,4,0,6,255,14,0,255,3,6,255,12,0,3,255,3,6,255,11,0,3,3,1,6,6,3,255,10,0,3,3,1,6,6,3,0,0,255,3,8,6,255,3,0,3,1,3,6,6,3,3,0,8,1,8,8,1,6,0,0,255,7,3,0,8,8,1,1,8,8,6,0,255,3,3,4,3,3,4,8,8,1,8,8,1,8,6,0,3,3,4,255,3,3,7,8,1,255,4,8,1,8,255,3,0,255,4,3,7,1,8,1,8,8,1,8,1,3,255,3,0,255,3,3,7,255,3,8,1,1,255,3,8,255,5,0,3,3,7,7,8,1,8,8,1,8,7,7,255,3,0,255,4,5,7,7,255,4,8,7,7,255,3,0,255,3,5,4,3,3,255,6,7,3,255,6,0,255,4,3,0,255,3,5,3,3,255,6,0,255,3,3,255,4,0,255,3,3,0,255,4,0,1,255,14,0,1,0,1,255,12,0,1,255,14,0,1,0,6,0,0,1,255,18,0,255,4,1,255,3,0,1,3,0,1,0,6,0,0,1,8,0,0,6,1,255,3,0,1,0,6,6,255,4,0,1,8,8,1,6,1,255,4,0,3,0,0,3,1,0,8,1,1,8,255,5,0,3,4,0,0,4,0,8,1,0,0,1,8,6,0,3,3,4,255,4,0,8,1,8,0,0,8,1,8,1,0,0,3,255,4,0,1,0,1,8,8,1,0,1,3,255,3,0,3,255,3,0,8,0,8,1,1,8,0,8,1,255,3,0,1,3,3,7,0,8,1,0,0,1,8,0,7,0,0,255,4,1,5,7,0,255,4,8,0,7,255,6,0,5,0,0,255,6,7,255,6,0,5,5,0,0,3,3,0,5,5,0,0,3,255,4,0,6,255,14,0,6,0,6,255,12,0,3,255,14,0,3,0,1,0,0,3,255,25,0,3,1,0,6,0,3,255,11,0,3,0,3,3,255,17,0,1,255,11,0,1,1,0,0,1,255,9,0,255,4,1,255,14,0,1,1,255,14,0,3,255,35,0,3,255,14,0,3,255,14,0,3,3,0,0,1,1,0,1,1,255,3,0,255,73,0,255,3,8,6,255,11,0,8,1,0,0,1,6,255,11,0,8,1,1,8,8,6,255,4,0,4,0,0,4,8,0,1,8,8,1,255,5,0,4,3,0,0,7,0,1,8,0,0,8,1,8,255,3,0,3,3,255,3,0,1,8,1,0,0,1,8,1,3,255,3,0,3,255,3,0,8,0,8,1,1,8,0,8,1,0,0,1,1,255,3,0,7,0,1,8,8,1,0,7,7,255,4,0,1,1,3,0,7,8,0,0,8,7,0,1,255,4,0,3,3,0,3,0,255,4,7,0,3,255,4,0,3,3,0,0,5,5,1,1,255,3,3,5,5,255,4,0,1,1,255,3,5,255,4,0,255,3,5,255,4,0,1,255,14,0,1,0,1,255,12,0,1,255,14,0,1,0,6,0,0,1,255,18,0,255,4,1,255,3,0,1,3,0,1,0,6,0,0,1,8,0,0,6,1,255,3,0,1,0,6,6,255,4,0,1,8,8,1,6,1,255,4,0,3,0,0,3,1,0,8,1,1,8,255,5,0,3,4,0,0,4,0,8,1,0,0,1,8,6,0,3,3,4,255,4,0,8,1,8,0,0,8,1,8,1,0,0,3,255,4,0,1,0,1,8,8,1,0,1,3,255,3,0,3,255,3,0,8,0,8,1,1,8,0,8,8,255,4,0,3,3,7,0,8,1,0,0,1,8,0,7,255,4,0,1,1,0,7,0,255,4,8,0,7,255,4,0,1,255,3,0,3,255,6,7,3,255,4,0,255,4,3,255,4,0,255,3,3,0,0,255,4,0,6,255,14,0,6,0,6,255,12,0,3,255,14,0,3,0,1,0,0,3,255,25,0,3,1,0,6,0,3,255,11,0,3,0,3,3,255,17,0,1,255,11,0,1,1,0,0,1,255,9,0,255,4,1,255,14,0,1,1,255,14,0,3,255,12,0,1,255,36,0,1,255,10,0,1,255,3,0,1,255,3,0,3,1,0,0,1,1,0,3,3};
uint16_t koopa_offsets[] = {0,199,390,479,640,832,926};
AnimationData koopa = {&koopa_colors[0], &koopa_data[0], &koopa_offsets[0], 9, 6, 16, 16};

View File

@ -1,4 +0,0 @@
class Effect {
public:
virtual void loop() {};
};

View File

@ -1,24 +0,0 @@
class Bell : public Effect {
private:
CRGB color_on = CRGB(0xFFFF00);
CRGB color_off= CRGB(0x000000);
boolean invert = false;
public:
void loop() {
for(int y=0; y<16; y++) {
for(int x=0; x<2; x++) {
for(int z=0; z<8; z++) {
leds[XYsafe(x*8+z, y)] = sprite_bell[y*2+x]>>(7-z) & 1 ^ invert ? color_on : color_off;
}
}
}
EVERY_N_MILLISECONDS(300) {
invert = !invert;
}
}
};

View File

@ -1,69 +0,0 @@
class Clock : public Effect {
private:
CRGB color_h = CRGB(0xFF0000);
CRGB color_m = CRGB(0x00FF00);
CRGB color_colon = CRGB(0xFFFF00);
void drawNumber(uint8_t number, int x, int y, CRGB color) {
char buffer[7];
sprintf(buffer, "%02d", number);
drawText(buffer, x, y, color);
}
void drawText(char *text, int x, int y, CRGB color) {
for (int i = 0; i < strlen(text); i++) {
drawSprite(font_char(numbers4x7, text[i]), x + i * 4, y, color);
}
}
unsigned char* font_char(unsigned char* font, char c) {
return &font[(c - 48) * 4];
}
void drawSprite(unsigned char* sprite, int xOffset, int yOffset, CRGB color) {
for ( byte y = 0; y < 7; y++) {
for ( byte x = 0; x < 4; x++) {
bool on = (sprite[x] >> y & 1) * 255;
if (on) {
leds[ XYsafe(x + xOffset, y + yOffset) ] = color;
}
}
}
}
public:
Clock() {}
void loop() {
clear();
drawNumber(ntpClient.getHours(), 0, 0, color_h);
drawNumber(ntpClient.getMinutes(), 8, 0, color_m);
/*if (ntpClient.getSeconds() & 1) {
leds[XYsafe(13, 2)] = color_colon;
leds[XYsafe(13, 5)] = color_colon;
}*/
drawNumber(ntpClient.getSeconds(), 8, 8, color_colon);
}
};
class SmallClock : public Effect {
private:
CRGB color_h = CRGB(0xFF0000);
CRGB color_m = CRGB(0x00FF00);
CRGB color_colon = CRGB(0xFFFF00);
public:
SmallClock() {}
void loop() {
clear();
int h = ntpClient.getHours();
drawDigit(numbers3x5, 3, 5, 0, 11, h/10, color_h);
drawDigit(numbers3x5, 3, 5, 4, 11, h%10, color_h);
int m = ntpClient.getMinutes();
drawDigit(numbers3x5, 3, 5, 9, 11, m/10, color_m);
drawDigit(numbers3x5, 3, 5, 13, 11, m%10, color_m);
if (ntpClient.getSeconds() & 1) {
leds[XYsafe(7, 12)] = color_colon;
leds[XYsafe(7, 14)] = color_colon;
}
}
};

View File

@ -1,68 +0,0 @@
class Sinematrix3 : public Effect {
private:
double pangle = 0;
double angle = 0;
double sx = 0;
double sy = 0;
double tx = 0;
double ty = 0;
double cx = 0;
double cy = 0;
double rcx = 0;
double rcy = 0;
double angle2 = 0;
double sx2 = 0;
double sy2 = 0;
double tx2 = 0;
double ty2 = 0;
double basecol = 0;
double fx = 1.0/(LED_WIDTH/PI);
double fy = 1.0/(LED_HEIGHT/PI);
Matrix rotate;
public:
Sinematrix3() {}
void loop() {
pangle = addmodpi( pangle, 0.0133 + (angle/256) );
angle = cos(pangle) * PI;
sx = addmodpi( sx, 0.00673 );
sy = addmodpi( sy, 0.00437 );
tx = addmodpi( tx, 0.00239 );
ty = addmodpi( ty, 0.00293 );
cx = addmodpi( cx, 0.00197 );
cy = addmodpi( cy, 0.00227 );
rcx = (LED_WIDTH/2) + (sin(cx) * LED_WIDTH);
rcy = (LED_HEIGHT/2) + (sin(cy) * LED_HEIGHT);
angle2 = addmodpi( angle2, 0.0029 );
sx2 = addmodpi( sx2, 0.0041);
sy2 = addmodpi( sy2, 0.0031);
tx2 = addmodpi( tx2, 0.0011 );
ty2 = addmodpi( ty2, 0.0023 );
basecol = addmod( basecol, 1.0, 0.007 );
rotate = {
.a11 = cos(angle),
.a12 = -sin(angle),
.a21 = sin(angle),
.a22 = cos(angle)
};
Matrix zoom = {
.a11 = sin(sx)/4.0 + 0.15,
.a12 = 0, //atan(cos(sx2)),
.a21 = 0, //atan(cos(sy2)),
.a22 = cos(sy)/4.0 + 0.15
};
Vector translate = {
.x1 = sin(tx) * LED_WIDTH,
.x2 = sin(ty) * LED_HEIGHT
};
for( int x = 0; x < LED_WIDTH; x++ ) {
for( int y = 0; y < LED_HEIGHT; y++ ) {
Vector c = add(multiply( multiply(rotate, zoom), { .x1 = x-rcx, .x2 = y-rcy } ), translate);
//Vector c2 = add(multiply( multiply(zoom2, rotate2), { .x1 = x, .x2 = y } ), translate2);
leds[XYsafe(x,y)] = CHSV((basecol+basefield(c.x1, c.x2))*255, 255, 255); //31+(sines(c2.x1-10, c2.x2-10)*224));
}
}
}
};

View File

@ -1,18 +0,0 @@
class Static : public Effect {
private:
CRGB color;
public:
Static(CRGB col) {
color = col;
}
void loop() {
EVERY_N_SECONDS(1) {
for ( int i = 0; i < LED_COUNT; i++) {
leds[i] = color;
}
FastLED.show();
}
}
};

225
effects.h Normal file
View File

@ -0,0 +1,225 @@
class Effect {
public:
virtual void loop() {};
};
class Bell : public Effect {
private:
CRGB color_on = CRGB(0xFFFF00);
CRGB color_off= CRGB(0x000000);
boolean invert = false;
public:
void loop() {
for(int y=0; y<16; y++) {
for(int x=0; x<2; x++) {
for(int z=0; z<8; z++) {
leds[XYsafe(x*8+z, y)] = sprite_bell[y*2+x]>>(7-z) & 1 ^ invert ? color_on : color_off;
}
}
}
EVERY_N_MILLISECONDS(300) {
invert = !invert;
}
}
};
class Clock : public Effect {
private:
CRGB color_h = CRGB(0xFF0000);
CRGB color_m = CRGB(0x00FF00);
CRGB color_colon = CRGB(0xFFFF00);
void drawNumber(uint8_t number, int x, int y, CRGB color) {
char buffer[7];
sprintf(buffer, "%02d", number);
drawText(buffer, x, y, color);
}
void drawText(char *text, int x, int y, CRGB color) {
for (int i = 0; i < strlen(text); i++) {
drawSprite(font_char(numbers4x7, text[i]), x + i * 4, y, color);
}
}
unsigned char* font_char(unsigned char* font, char c) {
return &font[(c - 48) * 4];
}
void drawSprite(unsigned char* sprite, int xOffset, int yOffset, CRGB color) {
for ( byte y = 0; y < 7; y++) {
for ( byte x = 0; x < 4; x++) {
bool on = (sprite[x] >> y & 1) * 255;
if (on) {
leds[ XYsafe(x + xOffset, y + yOffset) ] = color;
}
}
}
}
public:
Clock() {}
void loop() {
clear();
drawNumber(ntpClient.getHours(), 0, 0, color_h);
drawNumber(ntpClient.getMinutes(), 8, 0, color_m);
/*if (ntpClient.getSeconds() & 1) {
leds[XYsafe(13, 2)] = color_colon;
leds[XYsafe(13, 5)] = color_colon;
}*/
drawNumber(ntpClient.getSeconds(), 8, 8, color_colon);
}
};
class SmallClock : public Effect {
private:
CRGB color_h = CRGB(0xFF0000);
CRGB color_m = CRGB(0x00FF00);
CRGB color_colon = CRGB(0xFFFF00);
public:
SmallClock() {}
void loop() {
clear();
int h = ntpClient.getHours();
drawDigit(numbers3x5, 3, 5, 0, 11, h/10, color_h);
drawDigit(numbers3x5, 3, 5, 4, 11, h%10, color_h);
int m = ntpClient.getMinutes();
drawDigit(numbers3x5, 3, 5, 9, 11, m/10, color_m);
drawDigit(numbers3x5, 3, 5, 13, 11, m%10, color_m);
if (ntpClient.getSeconds() & 1) {
leds[XYsafe(7, 12)] = color_colon;
leds[XYsafe(7, 14)] = color_colon;
}
}
};
class Sinematrix3 : public Effect {
private:
double pangle = 0;
double angle = 0;
double sx = 0;
double sy = 0;
double tx = 0;
double ty = 0;
double cx = 0;
double cy = 0;
double rcx = 0;
double rcy = 0;
double angle2 = 0;
double sx2 = 0;
double sy2 = 0;
double tx2 = 0;
double ty2 = 0;
double basecol = 0;
double fx = 1.0/(LED_WIDTH/PI);
double fy = 1.0/(LED_HEIGHT/PI);
Matrix rotate;
public:
Sinematrix3() {}
void loop() {
pangle = addmodpi( pangle, 0.0133 + (angle/256) );
angle = cos(pangle) * PI;
sx = addmodpi( sx, 0.00673 );
sy = addmodpi( sy, 0.00437 );
tx = addmodpi( tx, 0.00239 );
ty = addmodpi( ty, 0.00293 );
cx = addmodpi( cx, 0.00197 );
cy = addmodpi( cy, 0.00227 );
rcx = (LED_WIDTH/2) + (sin(cx) * LED_WIDTH);
rcy = (LED_HEIGHT/2) + (sin(cy) * LED_HEIGHT);
angle2 = addmodpi( angle2, 0.0029 );
sx2 = addmodpi( sx2, 0.0041);
sy2 = addmodpi( sy2, 0.0031);
tx2 = addmodpi( tx2, 0.0011 );
ty2 = addmodpi( ty2, 0.0023 );
basecol = addmod( basecol, 1.0, 0.007 );
rotate = {
.a11 = cos(angle),
.a12 = -sin(angle),
.a21 = sin(angle),
.a22 = cos(angle)
};
Matrix zoom = {
.a11 = sin(sx)/4.0 + 0.15,
.a12 = 0, //atan(cos(sx2)),
.a21 = 0, //atan(cos(sy2)),
.a22 = cos(sy)/4.0 + 0.15
};
Vector translate = {
.x1 = sin(tx) * LED_WIDTH,
.x2 = sin(ty) * LED_HEIGHT
};
for( int x = 0; x < LED_WIDTH; x++ ) {
for( int y = 0; y < LED_HEIGHT; y++ ) {
Vector c = add(multiply( multiply(rotate, zoom), { .x1 = x-rcx, .x2 = y-rcy } ), translate);
//Vector c2 = add(multiply( multiply(zoom2, rotate2), { .x1 = x, .x2 = y } ), translate2);
leds[XYsafe(x,y)] = CHSV((basecol+basefield(c.x1, c.x2))*255, 255, 255); //31+(sines(c2.x1-10, c2.x2-10)*224));
}
}
}
};
class Static : public Effect {
private:
CRGB color;
public:
Static(CRGB col) {
color = col;
}
void loop() {
EVERY_N_SECONDS(1) {
for ( int i = 0; i < LED_COUNT; i++) {
leds[i] = color;
}
FastLED.show();
}
}
};
class Animation : public Effect {
private:
AnimationData *animation;
int frame = 0;
public:
Animation(AnimationData *anim) {
animation = anim;
}
void loop() {
CRGB colors[animation->color_count];
int led_index = 0;
for(int i=0; i<animation->color_count; i++) colors[i] = CRGB(animation->colors[i]);
for(int i=animation->offsets[frame]; i<animation->offsets[frame+1]; i++) {
if (animation->data[i]==255) { // Run-length encoded data
for (int j=0; j<animation->data[i+1]; j++) {
if (frame==0 || animation->data[i+2]>0) {
set(led_index, colors[animation->data[i+2]]);
}
led_index++;
}
i+=2;
} else {
if (frame==0 || animation->data[i]>0) {
set(led_index, colors[animation->data[i]]);
}
led_index++;
}
}
EVERY_N_MILLISECONDS(250) {
frame = (frame + 1) % animation->frame_count;
}
}
void set(int i, CRGB color) {
setPixel(i % animation->w, i / animation->h, color);
}
};
struct EffectEntry {
char* name;
Effect* effect;
};

View File

@ -15,6 +15,29 @@ int XYsafe(int x, int y) {
return y*LED_WIDTH+x;
}
void setPixel(int x, int y, CRGB color) {
if ( x >= LED_WIDTH) return;
if ( y >= LED_HEIGHT) return;
if ( x < 0) return;
if ( y < 0) return;
// Invert y
y = LED_HEIGHT - 1 - y;
if (y & 1) x = LED_WIDTH - 1 - x;
// Invert x
//x = LED_WIDTH - 1 - x;
leds[y*LED_WIDTH+x] = color;
}
void setPixel(int i, CRGB color) {
int x = i % LED_WIDTH;
int y = i / LED_WIDTH;
setPixel(x, y, color);
}
void clear() {
for ( byte y = 0; y < LED_HEIGHT; y++) {
for ( byte x = 0; x < LED_WIDTH; x++) {

View File

@ -12,15 +12,12 @@ WiFiClient wifi;
WiFiUDP ntpUDP;
NTPClient ntpClient(ntpUDP, NTP_SERVER, NTP_OFFSET, NTP_INTERVAL);
#include "effect.h"
#include "tools.h"
#include "functions.h"
#include "text.h"
#include "sprites.h"
#include "effect_sinematrix3.h"
#include "effect_clock.h"
#include "effect_bell.h"
#include "effect_static.h"
#include "animations.h"
#include "tools.h"
#include "effects.h"
void setup() {
// put your setup code here, to run once:
@ -39,14 +36,16 @@ Clock effect_clock;
SmallClock effect_small_clock;
Bell effect_bell;
Static effect_off(CRGB(0x000000));
Animation effect_koopa(&koopa);
Effect* current_effect = &effect_small_clock;
#define NUM_EFFECTS 5
#define NUM_EFFECTS 6
EffectEntry effects[NUM_EFFECTS] = {
{"bell", &effect_bell},
{"sinematrix3", &effect_sinematrix3},
{"clock", &effect_clock},
{"small_clock", &effect_small_clock},
{"koopa", &effect_koopa},
{"off", &effect_off}
};

2
text.h
View File

@ -114,7 +114,7 @@ static unsigned char numbers3x5[] = {
B01110, B10001, B01110, // 0
B01000, B11111, B00000, // 1
B01001, B10011, B01101, // 2
B10001, B10101, B01110, // 3
B10001, B10101, B01010, // 3
B11100, B00100, B11111, // 4
B11101, B10101, B10111, // 5
B01110, B10101, B10110, // 6

View File

@ -35,8 +35,3 @@ struct Vector add(struct Vector v1, struct Vector v2) {
};
return r;
}
struct EffectEntry {
char* name;
Effect* effect;
};