Implemented website
This commit is contained in:
@@ -8,7 +8,7 @@
|
|||||||
; Please visit documentation for the other options and examples
|
; Please visit documentation for the other options and examples
|
||||||
; https://docs.platformio.org/page/projectconf.html
|
; https://docs.platformio.org/page/projectconf.html
|
||||||
|
|
||||||
[env:esp01]
|
[env:d1_minid1_mini]
|
||||||
platform = espressif8266
|
platform = espressif8266
|
||||||
board = esp01
|
board = d1_mini
|
||||||
framework = arduino
|
framework = arduino
|
||||||
|
@@ -64,13 +64,14 @@ DEFINES += "VTABLES_IN_FLASH"
|
|||||||
|
|
||||||
OTHER_FILES += platformio.ini
|
OTHER_FILES += platformio.ini
|
||||||
|
|
||||||
SOURCES += src/main.cpp
|
HEADERS += src/ledsettings.h
|
||||||
HEADERS += src/ledcontroller.h
|
HEADERS += src/ledcontroller.h
|
||||||
HEADERS += src/pattern.h
|
HEADERS += src/pattern.h
|
||||||
HEADERS += src/patterns/rainbowpattern.h
|
SOURCES += src/main.cpp
|
||||||
HEADERS += src/patterns/rainbowwithglitterpattern.h
|
|
||||||
HEADERS += src/patterns/confettipattern.h
|
HEADERS += src/patterns/confettipattern.h
|
||||||
|
HEADERS += src/patterns/fire2012pattern.h
|
||||||
HEADERS += src/patterns/sineleonpattern.h
|
HEADERS += src/patterns/sineleonpattern.h
|
||||||
|
HEADERS += src/patterns/rainbowpattern.h
|
||||||
HEADERS += src/patterns/jugglepattern.h
|
HEADERS += src/patterns/jugglepattern.h
|
||||||
HEADERS += src/patterns/bpmpattern.h
|
HEADERS += src/patterns/bpmpattern.h
|
||||||
HEADERS += src/patterns/fire2012pattern.h
|
HEADERS += src/patterns/rainbowwithglitterpattern.h
|
||||||
|
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include <FastLED.h>
|
#include <FastLED.h>
|
||||||
|
|
||||||
|
#include "ledsettings.h"
|
||||||
#include "patterns/rainbowpattern.h"
|
#include "patterns/rainbowpattern.h"
|
||||||
#include "patterns/rainbowwithglitterpattern.h"
|
#include "patterns/rainbowwithglitterpattern.h"
|
||||||
#include "patterns/confettipattern.h"
|
#include "patterns/confettipattern.h"
|
||||||
@@ -13,13 +14,42 @@
|
|||||||
#include "patterns/bpmpattern.h"
|
#include "patterns/bpmpattern.h"
|
||||||
#include "patterns/fire2012pattern.h"
|
#include "patterns/fire2012pattern.h"
|
||||||
|
|
||||||
class LedController {
|
FASTLED_USING_NAMESPACE
|
||||||
|
|
||||||
|
class LedController
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
|
LedController() :
|
||||||
|
controller(FastLED.addLeds<WS2812, pin, RGB>(&leds[0], leds.size())),
|
||||||
|
m_rainbow(leds),
|
||||||
|
m_rainbowWithGlitter(leds),
|
||||||
|
m_confetti(leds),
|
||||||
|
m_sineleon(leds),
|
||||||
|
m_juggle(leds),
|
||||||
|
m_bpm(leds),
|
||||||
|
m_fire2012(leds),
|
||||||
|
patterns { &m_rainbow, &m_rainbowWithGlitter, &m_confetti, &m_sineleon, &m_juggle, &m_bpm, &m_fire2012 },
|
||||||
|
iter(patterns.begin())
|
||||||
|
{
|
||||||
|
controller.setCorrection(TypicalLEDStrip);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nextPattern()
|
||||||
|
{
|
||||||
|
iter++;
|
||||||
|
if (iter == patterns.end())
|
||||||
|
iter = patterns.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
void run()
|
||||||
|
{
|
||||||
|
(*iter)->run();
|
||||||
|
FastLED.show();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr auto NUM_LEDS = 100;
|
|
||||||
|
|
||||||
std::array<CRGB, NUM_LEDS> leds;
|
std::array<CRGB, NUM_LEDS> leds;
|
||||||
|
CLEDController &controller;
|
||||||
|
|
||||||
RainbowPattern m_rainbow;
|
RainbowPattern m_rainbow;
|
||||||
RainbowWithGlitterPattern m_rainbowWithGlitter;
|
RainbowWithGlitterPattern m_rainbowWithGlitter;
|
||||||
@@ -29,5 +59,7 @@ private:
|
|||||||
BpmPattern m_bpm;
|
BpmPattern m_bpm;
|
||||||
Fire2012Pattern m_fire2012;
|
Fire2012Pattern m_fire2012;
|
||||||
|
|
||||||
using PatternContainer = std::array<Pattern*, 7>;
|
public:
|
||||||
|
const PatternContainer patterns;
|
||||||
|
PatternContainer::const_iterator iter;
|
||||||
};
|
};
|
||||||
|
14
src/ledsettings.h
Normal file
14
src/ledsettings.h
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
|
||||||
|
#include <FastLED.h>
|
||||||
|
|
||||||
|
FASTLED_USING_NAMESPACE
|
||||||
|
|
||||||
|
class Pattern;
|
||||||
|
|
||||||
|
constexpr auto pin = 0;
|
||||||
|
constexpr auto NUM_LEDS = 100;
|
||||||
|
using LedContainer = std::array<CRGB, NUM_LEDS>;
|
||||||
|
using PatternContainer = std::array<Pattern*, 7>;
|
436
src/main.cpp
436
src/main.cpp
@@ -6,235 +6,240 @@
|
|||||||
#include <ESP8266WiFi.h>
|
#include <ESP8266WiFi.h>
|
||||||
#include <ESP8266WebServer.h>
|
#include <ESP8266WebServer.h>
|
||||||
|
|
||||||
#include <FastLED.h>
|
|
||||||
|
|
||||||
#include "ledcontroller.h"
|
#include "ledcontroller.h"
|
||||||
|
|
||||||
FASTLED_USING_NAMESPACE
|
|
||||||
|
|
||||||
constexpr auto WIFI_SSID = "McDonalds Free WiFi 2.4GHz";
|
constexpr auto WIFI_SSID = "McDonalds Free WiFi 2.4GHz";
|
||||||
constexpr auto WIFI_PASSWD = "Passwort_123";
|
constexpr auto WIFI_PASSWD = "Passwort_123";
|
||||||
|
|
||||||
LedController ledController;
|
LedController ledController;
|
||||||
|
|
||||||
constexpr auto pin = 0;
|
|
||||||
constexpr auto NUM_LEDS = 100;
|
|
||||||
|
|
||||||
std::array<CRGB, NUM_LEDS> leds;
|
|
||||||
|
|
||||||
ESP8266WebServer server(80);
|
ESP8266WebServer server(80);
|
||||||
|
|
||||||
uint8_t gHue = 0;
|
|
||||||
|
|
||||||
bool rotatePattern = true;
|
bool rotatePattern = true;
|
||||||
|
|
||||||
void addGlitter(fract8 chanceOfGlitter)
|
|
||||||
{
|
|
||||||
if(random8() < chanceOfGlitter)
|
|
||||||
leds[random16(leds.size())] += CRGB::White;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::array<std::function<void()>, 7> patterns {
|
|
||||||
[]()
|
|
||||||
{
|
|
||||||
fill_rainbow(&leds[0], leds.size(), gHue, 7);
|
|
||||||
},
|
|
||||||
[]()
|
|
||||||
{
|
|
||||||
fill_rainbow(&leds[0], leds.size(), gHue, 7);
|
|
||||||
addGlitter(80);
|
|
||||||
},
|
|
||||||
[]()
|
|
||||||
{
|
|
||||||
fadeToBlackBy(&leds[0], leds.size(), 10);
|
|
||||||
int pos = random16(leds.size());
|
|
||||||
leds[pos] += CHSV(gHue + random8(64), 200, 255);
|
|
||||||
},
|
|
||||||
[]()
|
|
||||||
{
|
|
||||||
fadeToBlackBy(&leds[0], leds.size(), 20);
|
|
||||||
int pos = beatsin16(13, 0, leds.size() - 1);
|
|
||||||
leds[pos] += CHSV(gHue, 255, 192);
|
|
||||||
},
|
|
||||||
[]()
|
|
||||||
{
|
|
||||||
fadeToBlackBy(&leds[0], leds.size(), 20);
|
|
||||||
byte dothue = 0;
|
|
||||||
for(int i = 0; i < 8; i++) {
|
|
||||||
leds[beatsin16(i+7, 0, leds.size() - 1)] |= CHSV(dothue, 200, 255);
|
|
||||||
dothue += 32;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[]()
|
|
||||||
{
|
|
||||||
uint8_t BeatsPerMinute = 62;
|
|
||||||
CRGBPalette16 palette = PartyColors_p;
|
|
||||||
uint8_t beat = beatsin8(BeatsPerMinute, 64, 255);
|
|
||||||
for(int i = 0; i < leds.size(); i++)
|
|
||||||
leds[i] = ColorFromPalette(palette, gHue+(i*2), beat-gHue+(i*10));
|
|
||||||
},
|
|
||||||
[]()
|
|
||||||
{
|
|
||||||
static constexpr auto COOLING = 55;
|
|
||||||
static constexpr auto SPARKING = 120;
|
|
||||||
static constexpr auto gReverseDirection = false;
|
|
||||||
|
|
||||||
// Array of temperature readings at each simulation cell
|
|
||||||
static std::array<byte, NUM_LEDS> heat;
|
|
||||||
|
|
||||||
// Step 1. Cool down every cell a little
|
|
||||||
for( int i = 0; i < leds.size(); i++) {
|
|
||||||
heat[i] = qsub8( heat[i], random8(0, ((COOLING * 10) / leds.size()) + 2));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 2. Heat from each cell drifts 'up' and diffuses a little
|
|
||||||
for( int k= leds.size() - 1; k >= 2; k--) {
|
|
||||||
heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2] ) / 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 3. Randomly ignite new 'sparks' of heat near the bottom
|
|
||||||
if( random8() < SPARKING ) {
|
|
||||||
int y = random8(7);
|
|
||||||
heat[y] = qadd8( heat[y], random8(160,255) );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 4. Map from heat cells to LED colors
|
|
||||||
for( int j = 0; j < leds.size(); j++) {
|
|
||||||
CRGB color = HeatColor( heat[j]);
|
|
||||||
int pixelnumber;
|
|
||||||
if( gReverseDirection ) {
|
|
||||||
pixelnumber = (leds.size()-1) - j;
|
|
||||||
} else {
|
|
||||||
pixelnumber = j;
|
|
||||||
}
|
|
||||||
leds[pixelnumber] = color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
auto iter = patterns.begin();
|
|
||||||
|
|
||||||
void nextPattern()
|
|
||||||
{
|
|
||||||
iter++;
|
|
||||||
if (iter == patterns.end())
|
|
||||||
iter = patterns.begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
void index_handler()
|
|
||||||
{
|
|
||||||
String str = "<html>"
|
|
||||||
"<head>"
|
|
||||||
"</head>"
|
|
||||||
"<body>"
|
|
||||||
"<h1>Total Entchen-Control 1.0</h1>"
|
|
||||||
"<p>"
|
|
||||||
"<a href=\"cmd?var=nextPattern&val=\">Next pattern</a> ";
|
|
||||||
if (rotatePattern)
|
|
||||||
str += "<a href=\"cmd?var=rotatePattern&val=false\">Disable pattern rotate</a>";
|
|
||||||
else
|
|
||||||
str += "<a href=\"cmd?var=rotatePattern&val=true\">Enable pattern rotate</a> ";
|
|
||||||
|
|
||||||
const auto index = std::distance(patterns.begin(), iter);
|
|
||||||
|
|
||||||
str += "</p>"
|
|
||||||
"<form action=\"cmd\" method=\"GET\">"
|
|
||||||
"<input type=\"hidden\" name=\"var\" value=\"setPattern\" />"
|
|
||||||
"<select name=\"val\" size=\"7\">"
|
|
||||||
"<option value=\"0\"";
|
|
||||||
if (index == 0)
|
|
||||||
str += " selected";
|
|
||||||
str += ">rainbow</option>"
|
|
||||||
"<option value=\"1\"";
|
|
||||||
if (index == 1)
|
|
||||||
str += " selected";
|
|
||||||
str += ">rainbowWithGlitter</option>"
|
|
||||||
"<option value=\"2\"";
|
|
||||||
if (index == 2)
|
|
||||||
str += " selected";
|
|
||||||
str += ">confetti</option>"
|
|
||||||
"<option value=\"3\"";
|
|
||||||
if (index == 3)
|
|
||||||
str += " selected";
|
|
||||||
str += ">sinelon</option>"
|
|
||||||
"<option value=\"4\"";
|
|
||||||
if (index == 4)
|
|
||||||
str += " selected";
|
|
||||||
str += ">juggle</option>"
|
|
||||||
"<option value=\"5\"";
|
|
||||||
if (index == 5)
|
|
||||||
str += " selected";
|
|
||||||
str += ">bpm</option>"
|
|
||||||
"<option value=\"6\"";
|
|
||||||
if (index == 6)
|
|
||||||
str += " selected";
|
|
||||||
str += ">Fire2012</option>"
|
|
||||||
"</select>"
|
|
||||||
"<button type=\"submit\">submit</button>"
|
|
||||||
"</form>"
|
|
||||||
"</body>"
|
|
||||||
"</html>";
|
|
||||||
|
|
||||||
server.sendHeader("Connection", "close");
|
|
||||||
server.send(200, "text/html", str.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void cmd_handler()
|
|
||||||
{
|
|
||||||
server.sendHeader("Connection", "close");
|
|
||||||
|
|
||||||
const String *var = nullptr;
|
|
||||||
const String *val = nullptr;
|
|
||||||
|
|
||||||
for (int i = 0; i < server.args(); i++)
|
|
||||||
{
|
|
||||||
if (server.argName(i) == "var")
|
|
||||||
var = &server.arg(i);
|
|
||||||
else if (server.argName(i) == "val")
|
|
||||||
val = &server.arg(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (var == nullptr || val == nullptr)
|
|
||||||
server.send(400, "text/html", "var or val missing");
|
|
||||||
|
|
||||||
if (*var == "nextPattern")
|
|
||||||
{
|
|
||||||
nextPattern();
|
|
||||||
server.send(200, "text/html", "ok");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if (*var == "setPattern")
|
|
||||||
{
|
|
||||||
const auto index = atoi(val->c_str());
|
|
||||||
if (index < 0 || index >= patterns.size())
|
|
||||||
{
|
|
||||||
server.send(500, "text/html", "out of range");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
iter = patterns.begin() + index;
|
|
||||||
|
|
||||||
server.send(200, "text/html", "ok");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if (*var == "rotatePattern")
|
|
||||||
{
|
|
||||||
rotatePattern = *val == "true";
|
|
||||||
server.send(200, "text/html", "ok");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
server.send(500, "text/html", "unknown var");
|
|
||||||
}
|
|
||||||
|
|
||||||
void setup()
|
void setup()
|
||||||
{
|
{
|
||||||
WiFi.begin(WIFI_SSID, WIFI_PASSWD);
|
WiFi.begin(WIFI_SSID, WIFI_PASSWD);
|
||||||
|
|
||||||
FastLED.addLeds<WS2812, pin, RGB>(&leds[0], leds.size()).setCorrection(TypicalLEDStrip);
|
server.on("/", HTTP_GET, []()
|
||||||
|
{
|
||||||
|
server.sendHeader("Connection", "close");
|
||||||
|
|
||||||
|
server.send(200, "text/html",
|
||||||
|
"<!doctype html>"
|
||||||
|
"<html lang=\"en\">"
|
||||||
|
"<head>"
|
||||||
|
"<!-- Required meta tags -->"
|
||||||
|
"<meta charset=\"utf-8\">"
|
||||||
|
"<meta name=\"viewport\" content=\"width=device-width, initial-scale=1, shrink-to-fit=no\">"
|
||||||
|
|
||||||
|
"<!-- Bootstrap CSS -->"
|
||||||
|
"<link rel=\"stylesheet\" href=\"https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css\" integrity=\"sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T\" crossorigin=\"anonymous\">"
|
||||||
|
|
||||||
|
"<style>"
|
||||||
|
".hidden {"
|
||||||
|
"display: none;"
|
||||||
|
"}"
|
||||||
|
"</style>"
|
||||||
|
|
||||||
|
"<title>Hello, world!</title>"
|
||||||
|
"</head>"
|
||||||
|
"<body>"
|
||||||
|
"<div class=\"container\">"
|
||||||
|
"<h1>Hello, world!</h1>"
|
||||||
|
"<p>"
|
||||||
|
"<a href=\"nextPattern\" class=\"softLink\">Next pattern</a>"
|
||||||
|
"<a href=\"setPatternRotate?val=true\" id=\"enableRotate\" class=\"softLink\">Enable automatic pattern rotate</a>"
|
||||||
|
"<a href=\"setPatternRotate?val=false\" id=\"disableRotate\" class=\"softLink\">Disable automatic pattern rotate</a>"
|
||||||
|
"</p>"
|
||||||
|
|
||||||
|
"<select id=\"patternSelect\"></select>"
|
||||||
|
|
||||||
|
"<input type=\"range\" min=\"0\" max=\"255\" id=\"brightness\" />"
|
||||||
|
"</div>"
|
||||||
|
|
||||||
|
"<script src=\"https://code.jquery.com/jquery-3.3.1.slim.min.js\" integrity=\"sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo\" crossorigin=\"anonymous\"></script>"
|
||||||
|
"<script>"
|
||||||
|
"jQuery(document).ready(function($){"
|
||||||
|
"$('.softLink').click(function(){"
|
||||||
|
"var xhr = new XMLHttpRequest();"
|
||||||
|
"xhr.open('GET', this.getAttribute('href'));"
|
||||||
|
"xhr.send();"
|
||||||
|
|
||||||
|
"return false;"
|
||||||
|
"});"
|
||||||
|
|
||||||
|
"$('#patternSelect').change(function(){"
|
||||||
|
"var xhr = new XMLHttpRequest();"
|
||||||
|
"xhr.open('GET', 'setPattern?val=' + this.selectedIndex);"
|
||||||
|
"xhr.send();"
|
||||||
|
"});"
|
||||||
|
|
||||||
|
"$('#brightness').change(function(){"
|
||||||
|
"var xhr = new XMLHttpRequest();"
|
||||||
|
"xhr.open('GET', 'setBrightness?val=' + this.value);"
|
||||||
|
"xhr.send();"
|
||||||
|
"});"
|
||||||
|
|
||||||
|
"var refreshStatus = function() {"
|
||||||
|
"var xhr = new XMLHttpRequest();"
|
||||||
|
"xhr.open('GET', 'status');"
|
||||||
|
"xhr.onload = function() {"
|
||||||
|
"var parsed = JSON.parse(xhr.responseText);"
|
||||||
|
|
||||||
|
"if (parsed.autoRotate) {"
|
||||||
|
"$('#enableRotate').addClass('hidden');"
|
||||||
|
"$('#disableRotate').removeClass('hidden');"
|
||||||
|
"} else {"
|
||||||
|
"$('#enableRotate').removeClass('hidden');"
|
||||||
|
"$('#disableRotate').addClass('hidden');"
|
||||||
|
"}"
|
||||||
|
|
||||||
|
"var select = $('#patternSelect');"
|
||||||
|
"select.empty();"
|
||||||
|
"select.attr('size', parsed.patterns.length);"
|
||||||
|
|
||||||
|
"for (var pattern of parsed.patterns) {"
|
||||||
|
"select.append($('<option>')"
|
||||||
|
".text(pattern.name)"
|
||||||
|
".attr('selected', pattern.selected)"
|
||||||
|
");"
|
||||||
|
"}"
|
||||||
|
|
||||||
|
"$('#brightness').val(parsed.brightness)"
|
||||||
|
"};"
|
||||||
|
"xhr.send();"
|
||||||
|
"};"
|
||||||
|
|
||||||
|
"refreshStatus();"
|
||||||
|
|
||||||
|
"setInterval(refreshStatus, 1000);"
|
||||||
|
"});"
|
||||||
|
"</script>"
|
||||||
|
"</body>"
|
||||||
|
"</html>"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
server.on("/status", HTTP_GET, []()
|
||||||
|
{
|
||||||
|
server.sendHeader("Connection", "close");
|
||||||
|
server.sendHeader("Access-Control-Allow-Origin", "*");
|
||||||
|
|
||||||
|
String str = "{";
|
||||||
|
|
||||||
|
str += "\"patterns\":[";
|
||||||
|
bool first = true;
|
||||||
|
for (auto pattern : ledController.patterns)
|
||||||
|
{
|
||||||
|
if (first)
|
||||||
|
first = false;
|
||||||
|
else
|
||||||
|
str += ',';
|
||||||
|
|
||||||
|
str += "{\"name\":\"";
|
||||||
|
str += pattern->name();
|
||||||
|
str += "\",\"selected\":";
|
||||||
|
str += (*ledController.iter) == pattern ? "true" : "false";
|
||||||
|
str += '}';
|
||||||
|
}
|
||||||
|
str += "],";
|
||||||
|
|
||||||
|
str += "\"autoRotate\":";
|
||||||
|
str += rotatePattern ? "true" : "false";
|
||||||
|
str += ",";
|
||||||
|
|
||||||
|
str += "\"brightness\":";
|
||||||
|
str += String(int(FastLED.getBrightness()));
|
||||||
|
|
||||||
|
str += "}";
|
||||||
|
|
||||||
|
server.send(200, "text/json", str.c_str());
|
||||||
|
});
|
||||||
|
|
||||||
|
server.on("/nextPattern", HTTP_GET, []()
|
||||||
|
{
|
||||||
|
ledController.nextPattern();
|
||||||
|
server.send(200, "text/html", "ok");
|
||||||
|
});
|
||||||
|
|
||||||
|
server.on("/setPattern", HTTP_GET, []()
|
||||||
|
{
|
||||||
|
const String *val = nullptr;
|
||||||
|
|
||||||
|
for (int i = 0; i < server.args(); i++)
|
||||||
|
if (server.argName(i) == "val")
|
||||||
|
val = &server.arg(i);
|
||||||
|
|
||||||
|
if (!val)
|
||||||
|
{
|
||||||
|
server.send(400, "text/html", "val missing");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto index = atoi(val->c_str());
|
||||||
|
if (index < 0 || index >= ledController.patterns.size())
|
||||||
|
{
|
||||||
|
server.send(400, "text/html", "out of range");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ledController.iter = ledController.patterns.begin() + index;
|
||||||
|
|
||||||
|
server.send(200, "text/html", "ok");
|
||||||
|
});
|
||||||
|
|
||||||
|
server.on("/setPatternRotate", HTTP_GET, []()
|
||||||
|
{
|
||||||
|
const String *val = nullptr;
|
||||||
|
|
||||||
|
for (int i = 0; i < server.args(); i++)
|
||||||
|
if (server.argName(i) == "val")
|
||||||
|
val = &server.arg(i);
|
||||||
|
|
||||||
|
if (!val)
|
||||||
|
{
|
||||||
|
server.send(400, "text/html", "val missing");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*val != "true" && *val != "false")
|
||||||
|
{
|
||||||
|
server.send(400, "text/html", "invalid val");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
rotatePattern = *val == "true";
|
||||||
|
|
||||||
|
server.send(200, "text/html", "ok");
|
||||||
|
});
|
||||||
|
|
||||||
|
server.on("/setBrightness", HTTP_GET, []()
|
||||||
|
{
|
||||||
|
const String *val = nullptr;
|
||||||
|
|
||||||
|
for (int i = 0; i < server.args(); i++)
|
||||||
|
if (server.argName(i) == "val")
|
||||||
|
val = &server.arg(i);
|
||||||
|
|
||||||
|
if (!val)
|
||||||
|
{
|
||||||
|
server.send(400, "text/html", "val missing");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto brightness = atoi(val->c_str());
|
||||||
|
if (brightness < 0 || brightness > 255)
|
||||||
|
{
|
||||||
|
server.send(400, "text/html", "out of range");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
FastLED.setBrightness(brightness);
|
||||||
|
|
||||||
|
server.send(200, "text/html", "ok");
|
||||||
|
});
|
||||||
|
|
||||||
server.on("/", HTTP_GET, index_handler);
|
|
||||||
server.on("/cmd", HTTP_GET, cmd_handler);
|
|
||||||
server.begin();
|
server.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -242,15 +247,14 @@ void loop()
|
|||||||
{
|
{
|
||||||
EVERY_N_MILLISECONDS(20)
|
EVERY_N_MILLISECONDS(20)
|
||||||
{
|
{
|
||||||
(*iter)();
|
ledController.run();
|
||||||
FastLED.show();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rotatePattern)
|
if (rotatePattern)
|
||||||
{
|
{
|
||||||
EVERY_N_SECONDS(10)
|
EVERY_N_SECONDS(10)
|
||||||
{
|
{
|
||||||
nextPattern();
|
ledController.nextPattern();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,5 +1,17 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
class Pattern {
|
#include "ledcontroller.h"
|
||||||
|
|
||||||
|
class Pattern {
|
||||||
|
public:
|
||||||
|
Pattern(LedContainer leds) :
|
||||||
|
leds(leds)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual const char *name() const = 0;
|
||||||
|
virtual void run() = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
LedContainer &leds;
|
||||||
};
|
};
|
||||||
|
@@ -2,6 +2,31 @@
|
|||||||
|
|
||||||
#include "pattern.h"
|
#include "pattern.h"
|
||||||
|
|
||||||
class BpmPattern : public Pattern {
|
#include <FastLED.h>
|
||||||
|
|
||||||
|
#include "ledsettings.h"
|
||||||
|
#include "ledcontroller.h"
|
||||||
|
|
||||||
|
FASTLED_USING_NAMESPACE
|
||||||
|
|
||||||
|
class BpmPattern : public Pattern {
|
||||||
|
public:
|
||||||
|
using Pattern::Pattern;
|
||||||
|
|
||||||
|
const char *name() const override
|
||||||
|
{
|
||||||
|
return "bpm";
|
||||||
|
}
|
||||||
|
|
||||||
|
void run() override
|
||||||
|
{
|
||||||
|
uint8_t BeatsPerMinute = 62;
|
||||||
|
CRGBPalette16 palette = PartyColors_p;
|
||||||
|
uint8_t beat = beatsin8(BeatsPerMinute, 64, 255);
|
||||||
|
for(int i = 0; i < leds.size(); i++)
|
||||||
|
leds[i] = ColorFromPalette(palette, gHue+(i*2), beat-(gHue++)+(i*10));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint8_t gHue = 0;
|
||||||
};
|
};
|
||||||
|
@@ -2,6 +2,29 @@
|
|||||||
|
|
||||||
#include "pattern.h"
|
#include "pattern.h"
|
||||||
|
|
||||||
class ConfettiPattern : public Pattern {
|
#include <FastLED.h>
|
||||||
|
|
||||||
|
#include "ledsettings.h"
|
||||||
|
#include "ledcontroller.h"
|
||||||
|
|
||||||
|
FASTLED_USING_NAMESPACE
|
||||||
|
|
||||||
|
class ConfettiPattern : public Pattern {
|
||||||
|
public:
|
||||||
|
using Pattern::Pattern;
|
||||||
|
|
||||||
|
const char *name() const override
|
||||||
|
{
|
||||||
|
return "confetti";
|
||||||
|
}
|
||||||
|
|
||||||
|
void run() override
|
||||||
|
{
|
||||||
|
fadeToBlackBy(&leds[0], leds.size(), 10);
|
||||||
|
int pos = random16(leds.size());
|
||||||
|
leds[pos] += CHSV(gHue++ + random8(64), 200, 255);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint8_t gHue = 0;
|
||||||
};
|
};
|
||||||
|
@@ -2,6 +2,62 @@
|
|||||||
|
|
||||||
#include "pattern.h"
|
#include "pattern.h"
|
||||||
|
|
||||||
class Fire2012Pattern : public Pattern {
|
#include <FastLED.h>
|
||||||
|
|
||||||
|
#include "ledsettings.h"
|
||||||
|
#include "ledcontroller.h"
|
||||||
|
|
||||||
|
FASTLED_USING_NAMESPACE
|
||||||
|
|
||||||
|
class Fire2012Pattern : public Pattern
|
||||||
|
{
|
||||||
|
static constexpr auto COOLING = 55;
|
||||||
|
static constexpr auto SPARKING = 120;
|
||||||
|
static constexpr auto gReverseDirection = false;
|
||||||
|
|
||||||
|
std::array<byte, NUM_LEDS> heat;
|
||||||
|
|
||||||
|
public:
|
||||||
|
using Pattern::Pattern;
|
||||||
|
|
||||||
|
const char *name() const override
|
||||||
|
{
|
||||||
|
return "fire2012";
|
||||||
|
}
|
||||||
|
|
||||||
|
void run() override
|
||||||
|
{
|
||||||
|
// Step 1. Cool down every cell a little
|
||||||
|
for( int i = 0; i < leds.size(); i++)
|
||||||
|
{
|
||||||
|
heat[i] = qsub8( heat[i], random8(0, ((COOLING * 10) / leds.size()) + 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 2. Heat from each cell drifts 'up' and diffuses a little
|
||||||
|
for( int k= leds.size() - 1; k >= 2; k--)
|
||||||
|
{
|
||||||
|
heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2] ) / 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 3. Randomly ignite new 'sparks' of heat near the bottom
|
||||||
|
if( random8() < SPARKING )
|
||||||
|
{
|
||||||
|
int y = random8(7);
|
||||||
|
heat[y] = qadd8( heat[y], random8(160,255) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 4. Map from heat cells to LED colors
|
||||||
|
for( int j = 0; j < leds.size(); j++)
|
||||||
|
{
|
||||||
|
CRGB color = HeatColor( heat[j]);
|
||||||
|
int pixelnumber;
|
||||||
|
|
||||||
|
if( gReverseDirection )
|
||||||
|
pixelnumber = (leds.size()-1) - j;
|
||||||
|
else
|
||||||
|
pixelnumber = j;
|
||||||
|
|
||||||
|
leds[pixelnumber] = color;
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
@@ -2,6 +2,29 @@
|
|||||||
|
|
||||||
#include "pattern.h"
|
#include "pattern.h"
|
||||||
|
|
||||||
class JugglePattern : public Pattern {
|
#include <FastLED.h>
|
||||||
|
|
||||||
|
#include "ledsettings.h"
|
||||||
|
#include "ledcontroller.h"
|
||||||
|
|
||||||
|
FASTLED_USING_NAMESPACE
|
||||||
|
|
||||||
|
class JugglePattern : public Pattern {
|
||||||
|
public:
|
||||||
|
using Pattern::Pattern;
|
||||||
|
|
||||||
|
const char *name() const override
|
||||||
|
{
|
||||||
|
return "juggle";
|
||||||
|
}
|
||||||
|
|
||||||
|
void run() override
|
||||||
|
{
|
||||||
|
fadeToBlackBy(&leds[0], leds.size(), 20);
|
||||||
|
byte dothue = 0;
|
||||||
|
for(int i = 0; i < 8; i++) {
|
||||||
|
leds[beatsin16(i+7, 0, leds.size() - 1)] |= CHSV(dothue, 200, 255);
|
||||||
|
dothue += 32;
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
@@ -2,6 +2,27 @@
|
|||||||
|
|
||||||
#include "pattern.h"
|
#include "pattern.h"
|
||||||
|
|
||||||
class RainbowPattern : public Pattern {
|
#include <FastLED.h>
|
||||||
|
|
||||||
|
#include "ledsettings.h"
|
||||||
|
#include "ledcontroller.h"
|
||||||
|
|
||||||
|
FASTLED_USING_NAMESPACE
|
||||||
|
|
||||||
|
class RainbowPattern : public Pattern {
|
||||||
|
public:
|
||||||
|
using Pattern::Pattern;
|
||||||
|
|
||||||
|
const char *name() const override
|
||||||
|
{
|
||||||
|
return "rainbow";
|
||||||
|
}
|
||||||
|
|
||||||
|
void run() override
|
||||||
|
{
|
||||||
|
fill_rainbow(&leds[0], leds.size(), gHue++, 7);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint8_t gHue = 0;
|
||||||
};
|
};
|
||||||
|
@@ -2,6 +2,32 @@
|
|||||||
|
|
||||||
#include "rainbowpattern.h"
|
#include "rainbowpattern.h"
|
||||||
|
|
||||||
class RainbowWithGlitterPattern : public RainbowPattern {
|
#include <FastLED.h>
|
||||||
|
|
||||||
|
#include "ledsettings.h"
|
||||||
|
#include "ledcontroller.h"
|
||||||
|
|
||||||
|
FASTLED_USING_NAMESPACE
|
||||||
|
|
||||||
|
class RainbowWithGlitterPattern : public RainbowPattern {
|
||||||
|
public:
|
||||||
|
using RainbowPattern::RainbowPattern;
|
||||||
|
|
||||||
|
const char *name() const override
|
||||||
|
{
|
||||||
|
return "rainbowWithGlitter";
|
||||||
|
}
|
||||||
|
|
||||||
|
void run() override
|
||||||
|
{
|
||||||
|
RainbowPattern::run();
|
||||||
|
addGlitter(80);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void addGlitter(fract8 chanceOfGlitter)
|
||||||
|
{
|
||||||
|
if(random8() < chanceOfGlitter)
|
||||||
|
leds[random16(leds.size())] += CRGB::White;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
@@ -2,6 +2,29 @@
|
|||||||
|
|
||||||
#include "pattern.h"
|
#include "pattern.h"
|
||||||
|
|
||||||
class SineleonPattern : public Pattern {
|
#include <FastLED.h>
|
||||||
|
|
||||||
|
#include "ledsettings.h"
|
||||||
|
#include "ledcontroller.h"
|
||||||
|
|
||||||
|
FASTLED_USING_NAMESPACE
|
||||||
|
|
||||||
|
class SineleonPattern : public Pattern {
|
||||||
|
public:
|
||||||
|
using Pattern::Pattern;
|
||||||
|
|
||||||
|
const char *name() const override
|
||||||
|
{
|
||||||
|
return "sineleon";
|
||||||
|
}
|
||||||
|
|
||||||
|
void run() override
|
||||||
|
{
|
||||||
|
fadeToBlackBy(&leds[0], leds.size(), 20);
|
||||||
|
int pos = beatsin16(13, 0, leds.size() - 1);
|
||||||
|
leds[pos] += CHSV(gHue++, 255, 192);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint8_t gHue = 0;
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user