From 81433310f9edcf283842f5faa19fc98541fc7d1e Mon Sep 17 00:00:00 2001 From: Fabian Schlenz Date: Tue, 21 May 2019 05:52:57 +0200 Subject: [PATCH] Initial commit. --- .gitignore | 1 + config.sample.h | 27 ++++++++ effect.h | 4 ++ effect_bell.h | 24 ++++++++ effect_clock.h | 45 ++++++++++++++ effect_sinematrix3.h | 68 ++++++++++++++++++++ effect_static.h | 18 ++++++ fastled.ino | 4 ++ functions.h | 43 +++++++++++++ mqtt.h | 43 +++++++++++++ ntp.ino | 7 +++ ota.ino | 32 ++++++++++ pitrix.ino | 78 +++++++++++++++++++++++ sprites.h | 18 ++++++ text.h | 144 +++++++++++++++++++++++++++++++++++++++++++ tools.h | 42 +++++++++++++ wifi.ino | 13 ++++ 17 files changed, 611 insertions(+) create mode 100644 .gitignore create mode 100644 config.sample.h create mode 100644 effect.h create mode 100644 effect_bell.h create mode 100644 effect_clock.h create mode 100644 effect_sinematrix3.h create mode 100644 effect_static.h create mode 100644 fastled.ino create mode 100644 functions.h create mode 100644 mqtt.h create mode 100644 ntp.ino create mode 100644 ota.ino create mode 100644 pitrix.ino create mode 100644 sprites.h create mode 100644 text.h create mode 100644 tools.h create mode 100644 wifi.ino diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0e56cf2 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +config.h diff --git a/config.sample.h b/config.sample.h new file mode 100644 index 0000000..799d9eb --- /dev/null +++ b/config.sample.h @@ -0,0 +1,27 @@ +#define WIFI_SSID "....." +#define WIFI_PASS "....." + +#define LED_WIDTH 16 +#define LED_HEIGHT 16 +#define LED_COUNT 256 +#define LED_TYPE WS2812B +#define DATA_PIN 14 +#define COLOR_ORDER GRB + +#define NTP_SERVER "pool.ntp.org" +#define NTP_INTERVAL 60000 +#define NTP_OFFSET 7200 + +#define MQTT_SERVER "....." +#define MQTT_PORT 1883 +#define MQTT_USER "pitrix" +#define MQTT_PASS "....." +#define MQTT_TOPIC_MODE "pitrix/mode" +#define MQTT_TOPIC_STATUS "pitrix/status" +#define MQTT_TOPIC_LOG "pitrix/log" + +#define OTA_HOSTNAME "pitrix" +#define OTA_STARTUP_DELAY 5 // How many seconds to wait at startup. Set to 0 to disable. + +#define FPS 50 +#define SHOW_TEXT_DELAY 100 diff --git a/effect.h b/effect.h new file mode 100644 index 0000000..fd91989 --- /dev/null +++ b/effect.h @@ -0,0 +1,4 @@ +class Effect { + public: + virtual void loop() {}; +}; diff --git a/effect_bell.h b/effect_bell.h new file mode 100644 index 0000000..bf5bd87 --- /dev/null +++ b/effect_bell.h @@ -0,0 +1,24 @@ +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; + } + } + + +}; diff --git a/effect_clock.h b/effect_clock.h new file mode 100644 index 0000000..f075515 --- /dev/null +++ b/effect_clock.h @@ -0,0 +1,45 @@ +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); + } +}; diff --git a/effect_sinematrix3.h b/effect_sinematrix3.h new file mode 100644 index 0000000..ad697cc --- /dev/null +++ b/effect_sinematrix3.h @@ -0,0 +1,68 @@ +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)); + } + } + } +}; diff --git a/effect_static.h b/effect_static.h new file mode 100644 index 0000000..91cf080 --- /dev/null +++ b/effect_static.h @@ -0,0 +1,18 @@ +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(); + } + } + + +}; diff --git a/fastled.ino b/fastled.ino new file mode 100644 index 0000000..28ca0ba --- /dev/null +++ b/fastled.ino @@ -0,0 +1,4 @@ +void fastled_setup() { + FastLED.addLeds(leds, LED_COUNT).setCorrection(TypicalLEDStrip); + FastLED.setBrightness(20); +} diff --git a/functions.h b/functions.h new file mode 100644 index 0000000..0e97950 --- /dev/null +++ b/functions.h @@ -0,0 +1,43 @@ +int XYsafe(int x, int y) { + if ( x >= LED_WIDTH) return 0; + if ( y >= LED_HEIGHT) return 0; + if ( x < 0) return 0; + if ( y < 0) return 0; + + // Invert y + y = LED_HEIGHT - 1 - y; + + if (y & 1) x = LED_WIDTH - 1 - x; + + // Invert x + //x = LED_WIDTH - 1 - x; + + return y*LED_WIDTH+x; +} + +void clear() { + for ( byte y = 0; y < LED_HEIGHT; y++) { + for ( byte x = 0; x < LED_WIDTH; x++) { + leds[ XYsafe(x, y)] = CHSV((16*y)+(47*x), 255, 42); + } + } +} + +inline double sines(double x, double y) { + return ((cos(x) * sin(y)) * 0.5) + 0.5; +} + +inline double basefield(double x, double y) { + return (cos(x) * sin(y) * cos(sqrt((x*x) + (y*y)))); +} + +inline double addmod(double x, double mod, double delta) { + x = x + delta; + while( x >= mod ) x -= mod; + while( x < 0.0 ) x += mod; + return x; +} + +inline double addmodpi(double x, double delta) { + return addmod(x, 2*PI, delta); +} diff --git a/mqtt.h b/mqtt.h new file mode 100644 index 0000000..d2c7daa --- /dev/null +++ b/mqtt.h @@ -0,0 +1,43 @@ +PubSubClient mqtt_client(wifi); +long mqtt_last_reconnect_attempt = 0; + +void mqtt_callback(char* topic, byte* payload, unsigned int length) { + payload[length] = '\0'; + + for (int i=0; i 5000) { + mqtt_last_reconnect_attempt = now; + if (mqtt_connect()) { + mqtt_last_reconnect_attempt = 0; + } + } + } else { + mqtt_client.loop(); + } +} diff --git a/ntp.ino b/ntp.ino new file mode 100644 index 0000000..e94649a --- /dev/null +++ b/ntp.ino @@ -0,0 +1,7 @@ +void ntp_setup() { + ntpClient.begin(); +} + +void ntp_loop() { + ntpClient.update(); +} diff --git a/ota.ino b/ota.ino new file mode 100644 index 0000000..bb9c297 --- /dev/null +++ b/ota.ino @@ -0,0 +1,32 @@ +void ota_setup() { + ArduinoOTA.onStart([]() { + String type; + if (ArduinoOTA.getCommand() == U_FLASH) + type = "sketch"; + else // U_SPIFFS + type = "filesystem"; + + // NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end() + Serial.println("OTA * Start updating " + type); + }); + ArduinoOTA.onEnd([]() { + Serial.println("\nOTA * End"); + }); + ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) { + Serial.printf("OTA * Progress: %u%%\r", (progress / (total / 100))); + }); + ArduinoOTA.onError([](ota_error_t error) { + Serial.printf("OTA * Error[%u]: ", error); + if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed"); + else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed"); + else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed"); + else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed"); + else if (error == OTA_END_ERROR) Serial.println("End Failed"); + }); + ArduinoOTA.setHostname(OTA_HOSTNAME); + ArduinoOTA.begin(); +} + +void ota_loop() { + ArduinoOTA.handle(); +} diff --git a/pitrix.ino b/pitrix.ino new file mode 100644 index 0000000..f6b19cc --- /dev/null +++ b/pitrix.ino @@ -0,0 +1,78 @@ +#include +#include +#include +#include +#include "FastLED.h" +#include +#include + +#include "config.h" +CRGB leds[LED_COUNT]; +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" + +void setup() { + // put your setup code here, to run once: + Serial.begin(74880); + Serial.println("Core * Starting"); + wifi_setup(); + ota_setup(); + fastled_setup(); + ntp_setup(); + mqtt_setup(); + Serial.println("Core * Setup complete"); +} + +Sinematrix3 effect_sinematrix3; +Clock effect_clock; +Bell effect_bell; +Static effect_off(CRGB(0x000000)); +Effect* current_effect = &effect_clock; + +#define NUM_EFFECTS 4 +EffectEntry effects[NUM_EFFECTS] = { + {"bell", &effect_bell}, + {"sinematrix3", &effect_sinematrix3}, + {"clock", &effect_clock}, + {"off", &effect_off} +}; + +#include "mqtt.h" + +uint8_t starting_up = OTA_STARTUP_DELAY; + +void loop() { + // put your main code here, to run repeatedly: + ota_loop(); + + if (starting_up > 0) { + EVERY_N_SECONDS(1) { + starting_up--; + clear(); + for (int i=0; iloop(); + FastLED.show(); + } +} diff --git a/sprites.h b/sprites.h new file mode 100644 index 0000000..166aa6c --- /dev/null +++ b/sprites.h @@ -0,0 +1,18 @@ +static unsigned char sprite_bell[] = { + 0b00000001, 0b10000000, + 0b00000010, 0b01000000, + 0b00001111, 0b11110000, + 0b00010000, 0b00001000, + 0b00100000, 0b00100100, + 0b00100000, 0b00110100, + 0b00100000, 0b00110100, + 0b00100000, 0b00110100, + 0b00100000, 0b00110100, + 0b00100000, 0b00110100, + 0b00100000, 0b00000100, + 0b01000000, 0b11111010, + 0b01000000, 0b00000010, + 0b00111111, 0b11111100, + 0b00000100, 0b00100000, + 0b00000011, 0b11000000 +}; diff --git a/text.h b/text.h new file mode 100644 index 0000000..d3af117 --- /dev/null +++ b/text.h @@ -0,0 +1,144 @@ +static unsigned char Font5x7[] = { + 0x00, 0x00, 0x00, 0x00, 0x00,// (space) + 0x00, 0x00, 0x5F, 0x00, 0x00,// ! + 0x00, 0x07, 0x00, 0x07, 0x00,// " + 0x14, 0x7F, 0x14, 0x7F, 0x14,// # + 0x24, 0x2A, 0x7F, 0x2A, 0x12,// $ + 0x23, 0x13, 0x08, 0x64, 0x62,// % + 0x36, 0x49, 0x55, 0x22, 0x50,// & + 0x00, 0x05, 0x03, 0x00, 0x00,// ' + 0x00, 0x1C, 0x22, 0x41, 0x00,// ( + 0x00, 0x41, 0x22, 0x1C, 0x00,// ) + 0x08, 0x2A, 0x1C, 0x2A, 0x08,// * + 0x08, 0x08, 0x3E, 0x08, 0x08,// + + 0x00, 0x50, 0x30, 0x00, 0x00,// , + 0x08, 0x08, 0x08, 0x08, 0x08,// - + 0x00, 0x60, 0x60, 0x00, 0x00,// . + 0x20, 0x10, 0x08, 0x04, 0x02,// / + 0x3E, 0x51, 0x49, 0x45, 0x3E,// 0 + 0x00, 0x42, 0x7F, 0x40, 0x00,// 1 + 0x42, 0x61, 0x51, 0x49, 0x46,// 2 + 0x21, 0x41, 0x45, 0x4B, 0x31,// 3 + 0x18, 0x14, 0x12, 0x7F, 0x10,// 4 + 0x27, 0x45, 0x45, 0x45, 0x39,// 5 + 0x3C, 0x4A, 0x49, 0x49, 0x30,// 6 + 0x01, 0x71, 0x09, 0x05, 0x03,// 7 + 0x36, 0x49, 0x49, 0x49, 0x36,// 8 + 0x06, 0x49, 0x49, 0x29, 0x1E,// 9 + 0x00, 0x36, 0x36, 0x00, 0x00,// : + 0x00, 0x56, 0x36, 0x00, 0x00,// ; + 0x00, 0x08, 0x14, 0x22, 0x41,// < + 0x14, 0x14, 0x14, 0x14, 0x14,// = + 0x41, 0x22, 0x14, 0x08, 0x00,// > + 0x02, 0x01, 0x51, 0x09, 0x06,// ? + 0x32, 0x49, 0x79, 0x41, 0x3E,// @ + 0x7E, 0x11, 0x11, 0x11, 0x7E,// A + 0x7F, 0x49, 0x49, 0x49, 0x36,// B + 0x3E, 0x41, 0x41, 0x41, 0x22,// C + 0x7F, 0x41, 0x41, 0x22, 0x1C,// D + 0x7F, 0x49, 0x49, 0x49, 0x41,// E + 0x7F, 0x09, 0x09, 0x01, 0x01,// F + 0x3E, 0x41, 0x41, 0x51, 0x32,// G + 0x7F, 0x08, 0x08, 0x08, 0x7F,// H + 0x00, 0x41, 0x7F, 0x41, 0x00,// I + 0x20, 0x40, 0x41, 0x3F, 0x01,// J + 0x7F, 0x08, 0x14, 0x22, 0x41,// K + 0x7F, 0x40, 0x40, 0x40, 0x40,// L + 0x7F, 0x02, 0x04, 0x02, 0x7F,// M + 0x7F, 0x04, 0x08, 0x10, 0x7F,// N + 0x3E, 0x41, 0x41, 0x41, 0x3E,// O + 0x7F, 0x09, 0x09, 0x09, 0x06,// P + 0x3E, 0x41, 0x51, 0x21, 0x5E,// Q + 0x7F, 0x09, 0x19, 0x29, 0x46,// R + 0x46, 0x49, 0x49, 0x49, 0x31,// S + 0x01, 0x01, 0x7F, 0x01, 0x01,// T + 0x3F, 0x40, 0x40, 0x40, 0x3F,// U + 0x1F, 0x20, 0x40, 0x20, 0x1F,// V + 0x7F, 0x20, 0x18, 0x20, 0x7F,// W + 0x63, 0x14, 0x08, 0x14, 0x63,// X + 0x03, 0x04, 0x78, 0x04, 0x03,// Y + 0x61, 0x51, 0x49, 0x45, 0x43,// Z + 0x00, 0x00, 0x7F, 0x41, 0x41,// [ + 0x02, 0x04, 0x08, 0x10, 0x20,// "\" + 0x41, 0x41, 0x7F, 0x00, 0x00,// ] + 0x04, 0x02, 0x01, 0x02, 0x04,// ^ + 0x40, 0x40, 0x40, 0x40, 0x40,// _ + 0x00, 0x01, 0x02, 0x04, 0x00,// ` + 0x20, 0x54, 0x54, 0x54, 0x78,// a + 0x7F, 0x48, 0x44, 0x44, 0x38,// b + 0x38, 0x44, 0x44, 0x44, 0x20,// c + 0x38, 0x44, 0x44, 0x48, 0x7F,// d + 0x38, 0x54, 0x54, 0x54, 0x18,// e + 0x08, 0x7E, 0x09, 0x01, 0x02,// f + 0x08, 0x14, 0x54, 0x54, 0x3C,// g + 0x7F, 0x08, 0x04, 0x04, 0x78,// h + 0x00, 0x44, 0x7D, 0x40, 0x00,// i + 0x20, 0x40, 0x44, 0x3D, 0x00,// j + 0x00, 0x7F, 0x10, 0x28, 0x44,// k + 0x00, 0x41, 0x7F, 0x40, 0x00,// l + 0x7C, 0x04, 0x18, 0x04, 0x78,// m + 0x7C, 0x08, 0x04, 0x04, 0x78,// n + 0x38, 0x44, 0x44, 0x44, 0x38,// o + 0x7C, 0x14, 0x14, 0x14, 0x08,// p + 0x08, 0x14, 0x14, 0x18, 0x7C,// q + 0x7C, 0x08, 0x04, 0x04, 0x08,// r + 0x48, 0x54, 0x54, 0x54, 0x20,// s + 0x04, 0x3F, 0x44, 0x40, 0x20,// t + 0x3C, 0x40, 0x40, 0x20, 0x7C,// u + 0x1C, 0x20, 0x40, 0x20, 0x1C,// v + 0x3C, 0x40, 0x30, 0x40, 0x3C,// w + 0x44, 0x28, 0x10, 0x28, 0x44,// x + 0x0C, 0x50, 0x50, 0x50, 0x3C,// y + 0x44, 0x64, 0x54, 0x4C, 0x44,// z + 0x00, 0x08, 0x36, 0x41, 0x00,// { + 0x00, 0x00, 0x7F, 0x00, 0x00,// | + 0x00, 0x41, 0x36, 0x08, 0x00,// } + 0x08, 0x08, 0x2A, 0x1C, 0x08,// -> + 0x08, 0x1C, 0x2A, 0x08, 0x08 // <- +}; + +static unsigned char numbers4x7[] = { + 0x3E, 0x51, 0x45, 0x3E,// 0 + 0x00, 0x42, 0x7F, 0x40,// 1 + 0x42, 0x61, 0x49, 0x46,// 2 + 0x21, 0x45, 0x4B, 0x31,// 3 + 0x18, 0x14, 0x7F, 0x10,// 4 + 0x27, 0x45, 0x45, 0x39,// 5 + 0x3C, 0x4A, 0x49, 0x30,// 6 + 0x01, 0x71, 0x09, 0x05, // 7 + 0x36, 0x49, 0x49, 0x36,// 8 + 0x06, 0x49, 0x29, 0x1E// 9 +}; + +unsigned char* Char(unsigned char* font, char c) { + return &font[(c - 32) * 5]; +} + +void DrawSprite(unsigned char* sprite, int length, int xOffset, int yOffset, CRGB color) { + // leds[ XYsafe(x, y) ] = CHSV(0, 0, 255); + for ( byte y = 0; y < 7; y++) { + for ( byte x = 0; x < 5; x++) { + bool on = (sprite[x] >> y & 1) * 255; + if (on) { + leds[ XYsafe(x + xOffset, y + yOffset) ] = color; + } + } + } +} + +void DrawText(char *text, int x, int y, CRGB color) { + for (int i = 0; i < strlen(text); i++) { + DrawSprite(Char(Font5x7, text[i]), 5, x + i * 6, y, color); + } +} + +void DrawTextOneFrame(char *text, int xOffset, int yOffset, CRGB color) { + DrawText(text, xOffset, yOffset, color); +} + +void DrawNumberOneFrame(uint32_t number, int xOffset, int yOffset, CRGB color) { + char buffer[7]; + //itoa(number,buffer,10); + sprintf(buffer, "%02d", number); + DrawTextOneFrame(buffer, xOffset, yOffset, color); +} diff --git a/tools.h b/tools.h new file mode 100644 index 0000000..cf9be04 --- /dev/null +++ b/tools.h @@ -0,0 +1,42 @@ +typedef struct Vector { + double x1; + double x2; +} Vector; + +typedef struct Matrix { + double a11; + double a12; + double a21; + double a22; +} Matrix; + +struct Matrix multiply(struct Matrix m1, struct Matrix m2) { + Matrix r = { + .a11 = m1.a11*m2.a11 + m1.a12*m2.a21, + .a12 = m1.a11*m2.a12 + m1.a12*m2.a22, + .a21 = m1.a21*m2.a11 + m1.a22*m2.a21, + .a22 = m1.a21*m2.a12 + m1.a22*m2.a22 + }; + return r; +}; + +struct Vector multiply(struct Matrix m, struct Vector v) { + Vector r = { + .x1 = (m.a11*v.x1) + (m.a12*v.x2), + .x2 = (m.a21*v.x1) + (m.a22*v.x2) + }; + return r; +} + +struct Vector add(struct Vector v1, struct Vector v2) { + Vector r = { + .x1 = v1.x1 + v2.x2, + .x2 = v1.x2 + v2.x2 + }; + return r; +} + +struct EffectEntry { + char* name; + Effect* effect; +}; diff --git a/wifi.ino b/wifi.ino new file mode 100644 index 0000000..91c6b13 --- /dev/null +++ b/wifi.ino @@ -0,0 +1,13 @@ +void wifi_setup() { + WiFi.mode(WIFI_STA); + WiFi.begin(WIFI_SSID, WIFI_PASS); + while (WiFi.waitForConnectResult() != WL_CONNECTED) { + Serial.println("WiFi * Connection Failed! Rebooting..."); + delay(5000); + ESP.restart(); + } + Serial.println("WiFi * Ready"); + Serial.print("WiFi * IP address: "); + Serial.println(WiFi.localIP()); +} +