Compare commits
16 Commits
wifi-exper
...
v1.0-no-ir
Author | SHA1 | Date | |
---|---|---|---|
ffc8a27211 | |||
c6a8af9e5a | |||
432fbb95d9 | |||
350feed191 | |||
410186e6a5 | |||
c17cea3426 | |||
407fd536c2 | |||
020b0b0e43 | |||
681c29a877 | |||
9bc7b7a5e7 | |||
e28346a6ee | |||
95e5f27caf | |||
608a7827d2 | |||
f49ca2d1f9 | |||
1e9b486cfd | |||
f5702fe80f |
50
README.md
50
README.md
@ -6,14 +6,38 @@ Control an addressable LED strip with an ESP8266 via a web browser or infrared r
|
|||||||
Hardware
|
Hardware
|
||||||
--------
|
--------
|
||||||
|
|
||||||
An ESP8266 development board, such as the [Adafruit HUZZAH ESP8266 Breakout]:
|
##### ESP8266 development board
|
||||||
|
|
||||||
|
[](https://www.aliexpress.com/item/WEMOS-D1-mini-Pro-16M-bytes-external-antenna-connector-ESP8266-WIFI-Internet-of-Things-development-board/32724692514.html)
|
||||||
|
|
||||||
|
[Wemos D1 Mini Pro & Headers](https://www.aliexpress.com/item/WEMOS-D1-mini-Pro-16M-bytes-external-antenna-connector-ESP8266-WIFI-Internet-of-Things-development-board/32724692514.html)
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
[](https://www.adafruit.com/products/2471)
|
[](https://www.adafruit.com/products/2471)
|
||||||
|
|
||||||
Addressable LED strip, such as the [Adafruit NeoPixel Ring]:
|
[Adafruit HUZZAH ESP8266 Breakout](https://www.adafruit.com/products/2471)
|
||||||
|
|
||||||
|
##### Addressable LED strip
|
||||||
|
|
||||||
[](https://www.adafruit.com/product/1586)
|
[](https://www.adafruit.com/product/1586)
|
||||||
|
|
||||||
|
[Adafruit NeoPixel Ring]
|
||||||
|
|
||||||
|
Other hardware:
|
||||||
|
|
||||||
|
* [3.3V to 5V Logic Level Shifter](http://www.digikey.com/product-detail/en/texas-instruments/SN74HCT245N/296-1612-5-ND/277258) (required if LEDs "glitch")
|
||||||
|
|
||||||
|
Recommended by [Adafruit NeoPixel "Best Practices"](https://learn.adafruit.com/adafruit-neopixel-uberguide/best-practices) to help protect LEDs from current onrush:
|
||||||
|
* [1000µF Capacitor](http://www.digikey.com/product-detail/en/panasonic-electronic-components/ECA-1EM102/P5156-ND/245015)
|
||||||
|
* [300 to 500 Ohm resistor](https://www.digikey.com/product-detail/en/stackpole-electronics-inc/CF14JT470R/CF14JT470RCT-ND/1830342)
|
||||||
|
|
||||||
|
Optional shield to make everything more tidy:
|
||||||
|
|
||||||
|
[](https://www.tindie.com/products/jasoncoon/wemos-d1-mini-esp8266-led-and-level-shifter-shield/)
|
||||||
|
|
||||||
|
[Wemos D1 Mini ESP8266 LED & Level Shifter Shield](https://www.tindie.com/products/jasoncoon/wemos-d1-mini-esp8266-led-and-level-shifter-shield)
|
||||||
|
|
||||||
Features
|
Features
|
||||||
--------
|
--------
|
||||||
* Turn the NeoPixel Ring on and off
|
* Turn the NeoPixel Ring on and off
|
||||||
@ -30,17 +54,27 @@ Patterns are requested by the app from the ESP8266, so as new patterns are added
|
|||||||
|
|
||||||
The web app is stored in SPIFFS (on-board flash memory).
|
The web app is stored in SPIFFS (on-board flash memory).
|
||||||
|
|
||||||
The web app is a single page app with separate files for js and css, using [jQuery](https://jquery.com) and [Bootstrap](http://getbootstrap.com). It has buttons for On/Off, a slider for brightness, a pattern selector, and a color picker (using [jQuery MiniColors](http://labs.abeautifulsite.net/jquery-minicolors)). Event handlers for the controls are wired up, so you don't have to click a 'Send' button after making changes. The brightness slider and the color picker use a delayed event handler, to prevent from flooding the ESP8266 web server with too many requests too quickly.
|
The web app is a single page app that uses [jQuery](https://jquery.com) and [Bootstrap](http://getbootstrap.com). It has buttons for On/Off, a slider for brightness, a pattern selector, and a color picker (using [jQuery MiniColors](http://labs.abeautifulsite.net/jquery-minicolors)). Event handlers for the controls are wired up, so you don't have to click a 'Send' button after making changes. The brightness slider and the color picker use a delayed event handler, to prevent from flooding the ESP8266 web server with too many requests too quickly.
|
||||||
|
|
||||||
The only drawback to SPIFFS that I've found so far is uploading the files is extremely slow, requiring several minutes, regardless of how large the files are. It's so slow that I've been just developing the web app and debugging locally on my desktop (with a hard-coded IP for the ESP8266), before uploading to SPIFFS and testing on the ESP8266.
|
|
||||||
|
|
||||||
|
The only drawback to SPIFFS that I've found so far is uploading the files can be extremely slow, requiring several minutes, sometimes regardless of how large the files are. It can be so slow that I've been just developing the web app and debugging locally on my desktop (with a hard-coded IP for the ESP8266), before uploading to SPIFFS and testing on the ESP8266.
|
||||||
|
|
||||||
Installing
|
Installing
|
||||||
-----------
|
-----------
|
||||||
|
The app is installed via the Arduino IDE which can be [downloaded here](https://www.arduino.cc/en/main/software). The ESP8266 boards will need to be added to the Arduino IDE which is achieved as follows. Click File > Preferences and copy and paste the URL "http://arduino.esp8266.com/stable/package_esp8266com_index.json" into the Additional Boards Manager URLs field. Click OK. Click Tools > Boards: ... > Boards Manager. Find and click on ESP8266 (using the Search function may expedite this). Click on Install. After installation, click on Close and then select your ESP8266 board from the Tools > Board: ... menu.
|
||||||
|
|
||||||
The web app needs to be uploaded to the ESP8266's SPIFFS. You can do this within the Arduino IDE after installing the [Arduino ESP8266FS tool](https://github.com/esp8266/Arduino/blob/master/doc/filesystem.md#uploading-files-to-file-system).
|
The app depends on the following libraries. They must either be downloaded from GitHub and placed in the Arduino 'libraries' folder, or installed as [described here](https://www.arduino.cc/en/Guide/Libraries) by using the Arduino library manager.
|
||||||
|
|
||||||
With ESP8266FS installed run the sketch and then upload the web app using `ESP8266 Sketch Data Upload` command in the Arduino Tools menu.
|
* [FastLED](https://github.com/FastLED/FastLED)
|
||||||
|
* [IRremoteESP8266](https://github.com/sebastienwarin/IRremoteESP8266)
|
||||||
|
* [Arduino WebSockets](https://github.com/Links2004/arduinoWebSockets)
|
||||||
|
|
||||||
|
Download the app code from GitHub using the green Clone or Download button from [the GitHub project main page](https://github.com/jasoncoon/esp8266-fastled-webserver) and click Download ZIP. Decompress the ZIP file in your Arduino sketch folder.
|
||||||
|
|
||||||
|
The web app needs to be uploaded to the ESP8266's SPIFFS. You can do this within the Arduino IDE after installing the [Arduino ESP8266FS tool](http://esp8266.github.io/Arduino/versions/2.3.0/doc/filesystem.html#uploading-files-to-file-system).
|
||||||
|
|
||||||
|
With ESP8266FS installed upload the web app using `ESP8266 Sketch Data Upload` command in the Arduino Tools menu.
|
||||||
|
|
||||||
|
Then enter your wi-fi network SSID and password in the .ino file, and upload the sketch using the Upload button.
|
||||||
|
|
||||||
Compression
|
Compression
|
||||||
-----------
|
-----------
|
||||||
@ -61,7 +95,7 @@ The firmware implements basic [RESTful web services](https://en.wikipedia.org/wi
|
|||||||
Infrared Remote Control
|
Infrared Remote Control
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
Control via infrared remote control is also supported, via the [ESP8266 port of the IRremote library](https://github.com/markszabo/IRremoteESP8266).
|
Control via infrared remote control is also supported, via the [ESP8266 port of the IRremote library](https://github.com/sebastienwarin/IRremoteESP8266).
|
||||||
|
|
||||||
[Adafruit NeoPixel Ring]:https://www.adafruit.com/product/1586
|
[Adafruit NeoPixel Ring]:https://www.adafruit.com/product/1586
|
||||||
[Adafruit HUZZAH ESP8266 Breakout]:https://www.adafruit.com/products/2471
|
[Adafruit HUZZAH ESP8266 Breakout]:https://www.adafruit.com/products/2471
|
||||||
|
@ -52,9 +52,13 @@
|
|||||||
<label for="inputPattern" class="col-sm-2 control-label">Pattern</label>
|
<label for="inputPattern" class="col-sm-2 control-label">Pattern</label>
|
||||||
<div class="col-sm-6">
|
<div class="col-sm-6">
|
||||||
<select class="form-control" id="inputPattern">
|
<select class="form-control" id="inputPattern">
|
||||||
<option>Rainbow</option>
|
</select>
|
||||||
<option>Sinelon</option>
|
</div>
|
||||||
<option>Juggle</option>
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="inputPalette" class="col-sm-2 control-label">Palette</label>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<select class="form-control" id="inputPalette">
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -70,6 +70,10 @@ $("#inputPattern").change(function() {
|
|||||||
setPattern($("#inputPattern option:selected").index());
|
setPattern($("#inputPattern option:selected").index());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$("#inputPalette").change(function() {
|
||||||
|
setPalette($("#inputPalette option:selected").index());
|
||||||
|
});
|
||||||
|
|
||||||
$("#inputColor").change(function() {
|
$("#inputColor").change(function() {
|
||||||
if(ignoreColorChange) return;
|
if(ignoreColorChange) return;
|
||||||
|
|
||||||
@ -105,15 +109,30 @@ function getAll() {
|
|||||||
|
|
||||||
updatePowerButtons(data.power);
|
updatePowerButtons(data.power);
|
||||||
|
|
||||||
|
// clear pattern list
|
||||||
$("#inputPattern").find("option").remove();
|
$("#inputPattern").find("option").remove();
|
||||||
|
|
||||||
|
// load pattern list
|
||||||
for(var i = 0; i < data.patterns.length; i++) {
|
for(var i = 0; i < data.patterns.length; i++) {
|
||||||
var pattern = data.patterns[i];
|
var pattern = data.patterns[i];
|
||||||
$("#inputPattern").append("<option value='" + i + "'>" + pattern + "</option>");
|
$("#inputPattern").append("<option value='" + i + "'>" + pattern + "</option>");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// select the current pattern
|
||||||
$("#inputPattern").val(data.currentPattern.index);
|
$("#inputPattern").val(data.currentPattern.index);
|
||||||
|
|
||||||
|
// clear palette list
|
||||||
|
$("#inputPalette").find("option").remove();
|
||||||
|
|
||||||
|
// load palette list
|
||||||
|
for(var i = 0; i < data.palettes.length; i++) {
|
||||||
|
var palette = data.palettes[i];
|
||||||
|
$("#inputPalette").append("<option value='" + i + "'>" + palette + "</option>");
|
||||||
|
}
|
||||||
|
|
||||||
|
// select the current palette
|
||||||
|
$("#inputPalette").val(data.currentPalette.index);
|
||||||
|
|
||||||
$("#status").html("Ready");
|
$("#status").html("Ready");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -154,6 +173,12 @@ function setPattern(value) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setPalette(value) {
|
||||||
|
$.post(urlBase + "palette?value=" + value, function(data) {
|
||||||
|
$("#status").html("Set Palette: " + data.name);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function delaySetColor(value) {
|
function delaySetColor(value) {
|
||||||
clearTimeout(colorTimer);
|
clearTimeout(colorTimer);
|
||||||
colorTimer = setTimeout(function() {
|
colorTimer = setTimeout(function() {
|
||||||
|
@ -1,20 +1,23 @@
|
|||||||
/*
|
/*
|
||||||
* ESP8266 + FastLED + IR Remote + MSGEQ7: https://github.com/jasoncoon/esp8266-fastled-webserver
|
ESP8266 + FastLED + IR Remote + MSGEQ7: https://github.com/jasoncoon/esp8266-fastled-webserver
|
||||||
* Copyright (C) 2015 Jason Coon
|
Copyright (C) 2015 Jason Coon
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
(at your option) any later version.
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define FASTLED_INTERRUPT_RETRY_COUNT 1
|
||||||
|
// #define FASTLED_ALLOW_INTERRUPTS 0
|
||||||
|
|
||||||
#include "FastLED.h"
|
#include "FastLED.h"
|
||||||
FASTLED_USING_NAMESPACE
|
FASTLED_USING_NAMESPACE
|
||||||
@ -27,13 +30,13 @@ extern "C" {
|
|||||||
#include <ESP8266WebServer.h>
|
#include <ESP8266WebServer.h>
|
||||||
#include <FS.h>
|
#include <FS.h>
|
||||||
#include <EEPROM.h>
|
#include <EEPROM.h>
|
||||||
#include <IRremoteESP8266.h>
|
//#include <IRremoteESP8266.h>
|
||||||
#include "GradientPalettes.h"
|
#include "GradientPalettes.h"
|
||||||
|
|
||||||
#define RECV_PIN 12
|
//#define RECV_PIN 12
|
||||||
IRrecv irReceiver(RECV_PIN);
|
//IRrecv irReceiver(RECV_PIN);
|
||||||
|
|
||||||
#include "Commands.h"
|
//#include "Commands.h"
|
||||||
|
|
||||||
const bool apMode = false;
|
const bool apMode = false;
|
||||||
|
|
||||||
@ -46,12 +49,12 @@ const char* password = "";
|
|||||||
|
|
||||||
ESP8266WebServer server(80);
|
ESP8266WebServer server(80);
|
||||||
|
|
||||||
#define DATA_PIN 13 // for Huzzah: Pins w/o special function: #4, #5, #12, #13, #14; // #16 does not work :(
|
#define DATA_PIN D5 // for Huzzah: Pins w/o special function: #4, #5, #12, #13, #14; // #16 does not work :(
|
||||||
#define LED_TYPE WS2812
|
#define LED_TYPE WS2811
|
||||||
#define COLOR_ORDER GRB
|
#define COLOR_ORDER RGB
|
||||||
#define NUM_LEDS 24
|
#define NUM_LEDS 400
|
||||||
|
|
||||||
#define MILLI_AMPS 2000 // IMPORTANT: set here the max milli-Amps of your power supply 5V 2A = 2000
|
#define MILLI_AMPS 1400 // IMPORTANT: set here the max milli-Amps of your power supply 5V 2A = 2000
|
||||||
#define FRAMES_PER_SECOND 120 // here you can control the speed. With the Access Point / Web Server the animations run a bit slower.
|
#define FRAMES_PER_SECOND 120 // here you can control the speed. With the Access Point / Web Server the animations run a bit slower.
|
||||||
|
|
||||||
CRGB leds[NUM_LEDS];
|
CRGB leds[NUM_LEDS];
|
||||||
@ -89,6 +92,8 @@ bool autoplayEnabled = false;
|
|||||||
uint8_t autoPlayDurationSeconds = 10;
|
uint8_t autoPlayDurationSeconds = 10;
|
||||||
unsigned int autoPlayTimeout = 0;
|
unsigned int autoPlayTimeout = 0;
|
||||||
|
|
||||||
|
uint8_t currentPaletteIndex = 0;
|
||||||
|
|
||||||
uint8_t gHue = 0; // rotating "base color" used by many of the patterns
|
uint8_t gHue = 0; // rotating "base color" used by many of the patterns
|
||||||
|
|
||||||
CRGB solidColor = CRGB::Blue;
|
CRGB solidColor = CRGB::Blue;
|
||||||
@ -104,6 +109,7 @@ void setup(void) {
|
|||||||
//FastLED.addLeds<LED_TYPE,DATA_PIN,CLK_PIN,COLOR_ORDER>(leds, NUM_LEDS); // for APA102 (Dotstar)
|
//FastLED.addLeds<LED_TYPE,DATA_PIN,CLK_PIN,COLOR_ORDER>(leds, NUM_LEDS); // for APA102 (Dotstar)
|
||||||
FastLED.setCorrection(TypicalLEDStrip);
|
FastLED.setCorrection(TypicalLEDStrip);
|
||||||
FastLED.setBrightness(brightness);
|
FastLED.setBrightness(brightness);
|
||||||
|
FastLED.setDither(false);
|
||||||
FastLED.setMaxPowerInVoltsAndMilliamps(5, MILLI_AMPS);
|
FastLED.setMaxPowerInVoltsAndMilliamps(5, MILLI_AMPS);
|
||||||
fill_solid(leds, NUM_LEDS, solidColor);
|
fill_solid(leds, NUM_LEDS, solidColor);
|
||||||
FastLED.show();
|
FastLED.show();
|
||||||
@ -111,7 +117,9 @@ void setup(void) {
|
|||||||
EEPROM.begin(512);
|
EEPROM.begin(512);
|
||||||
loadSettings();
|
loadSettings();
|
||||||
|
|
||||||
irReceiver.enableIRIn(); // Start the receiver
|
FastLED.setBrightness(brightness);
|
||||||
|
|
||||||
|
// irReceiver.enableIRIn(); // Start the receiver
|
||||||
|
|
||||||
Serial.println();
|
Serial.println();
|
||||||
Serial.print( F("Heap: ") ); Serial.println(system_get_free_heap_size());
|
Serial.print( F("Heap: ") ); Serial.println(system_get_free_heap_size());
|
||||||
@ -245,6 +253,16 @@ void setup(void) {
|
|||||||
sendBrightness();
|
sendBrightness();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
server.on("/palette", HTTP_GET, []() {
|
||||||
|
sendPalette();
|
||||||
|
});
|
||||||
|
|
||||||
|
server.on("/palette", HTTP_POST, []() {
|
||||||
|
String value = server.arg("value");
|
||||||
|
setPalette(value.toInt());
|
||||||
|
sendPalette();
|
||||||
|
});
|
||||||
|
|
||||||
server.serveStatic("/index.htm", SPIFFS, "/index.htm");
|
server.serveStatic("/index.htm", SPIFFS, "/index.htm");
|
||||||
server.serveStatic("/fonts", SPIFFS, "/fonts", "max-age=86400");
|
server.serveStatic("/fonts", SPIFFS, "/fonts", "max-age=86400");
|
||||||
server.serveStatic("/js", SPIFFS, "/js");
|
server.serveStatic("/js", SPIFFS, "/js");
|
||||||
@ -260,7 +278,6 @@ void setup(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
typedef void (*Pattern)();
|
typedef void (*Pattern)();
|
||||||
typedef Pattern PatternList[];
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Pattern pattern;
|
Pattern pattern;
|
||||||
String name;
|
String name;
|
||||||
@ -283,13 +300,43 @@ PatternAndNameList patterns = {
|
|||||||
|
|
||||||
const uint8_t patternCount = ARRAY_SIZE(patterns);
|
const uint8_t patternCount = ARRAY_SIZE(patterns);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
CRGBPalette16 palette;
|
||||||
|
String name;
|
||||||
|
} PaletteAndName;
|
||||||
|
typedef PaletteAndName PaletteAndNameList[];
|
||||||
|
|
||||||
|
const CRGBPalette16 palettes[] = {
|
||||||
|
RainbowColors_p,
|
||||||
|
RainbowStripeColors_p,
|
||||||
|
CloudColors_p,
|
||||||
|
LavaColors_p,
|
||||||
|
OceanColors_p,
|
||||||
|
ForestColors_p,
|
||||||
|
PartyColors_p,
|
||||||
|
HeatColors_p
|
||||||
|
};
|
||||||
|
|
||||||
|
const uint8_t paletteCount = ARRAY_SIZE(palettes);
|
||||||
|
|
||||||
|
const String paletteNames[paletteCount] = {
|
||||||
|
"Rainbow",
|
||||||
|
"Rainbow Stripe",
|
||||||
|
"Cloud",
|
||||||
|
"Lava",
|
||||||
|
"Ocean",
|
||||||
|
"Forest",
|
||||||
|
"Party",
|
||||||
|
"Heat",
|
||||||
|
};
|
||||||
|
|
||||||
void loop(void) {
|
void loop(void) {
|
||||||
// Add entropy to random number generator; we use a lot of it.
|
// Add entropy to random number generator; we use a lot of it.
|
||||||
random16_add_entropy(random(65535));
|
random16_add_entropy(random(65535));
|
||||||
|
|
||||||
server.handleClient();
|
server.handleClient();
|
||||||
|
|
||||||
handleIrInput();
|
// handleIrInput();
|
||||||
|
|
||||||
if (power == 0) {
|
if (power == 0) {
|
||||||
fill_solid(leds, NUM_LEDS, CRGB::Black);
|
fill_solid(leds, NUM_LEDS, CRGB::Black);
|
||||||
@ -331,212 +378,212 @@ void loop(void) {
|
|||||||
FastLED.delay(1000 / FRAMES_PER_SECOND);
|
FastLED.delay(1000 / FRAMES_PER_SECOND);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleIrInput()
|
//void handleIrInput()
|
||||||
{
|
//{
|
||||||
InputCommand command = readCommand(defaultHoldDelay);
|
// InputCommand command = readCommand(defaultHoldDelay);
|
||||||
|
//
|
||||||
if (command != InputCommand::None) {
|
// if (command != InputCommand::None) {
|
||||||
Serial.print("command: ");
|
// Serial.print("command: ");
|
||||||
Serial.println((int) command);
|
// Serial.println((int) command);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
switch (command) {
|
// switch (command) {
|
||||||
case InputCommand::Up: {
|
// case InputCommand::Up: {
|
||||||
adjustPattern(true);
|
// adjustPattern(true);
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
case InputCommand::Down: {
|
// case InputCommand::Down: {
|
||||||
adjustPattern(false);
|
// adjustPattern(false);
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
case InputCommand::Power: {
|
// case InputCommand::Power: {
|
||||||
power = power == 0 ? 1 : 0;
|
// power = power == 0 ? 1 : 0;
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
case InputCommand::BrightnessUp: {
|
// case InputCommand::BrightnessUp: {
|
||||||
adjustBrightness(true);
|
// adjustBrightness(true);
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
case InputCommand::BrightnessDown: {
|
// case InputCommand::BrightnessDown: {
|
||||||
adjustBrightness(false);
|
// adjustBrightness(false);
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
case InputCommand::PlayMode: { // toggle pause/play
|
// case InputCommand::PlayMode: { // toggle pause/play
|
||||||
autoplayEnabled = !autoplayEnabled;
|
// autoplayEnabled = !autoplayEnabled;
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
// pattern buttons
|
// // pattern buttons
|
||||||
|
//
|
||||||
case InputCommand::Pattern1: {
|
// case InputCommand::Pattern1: {
|
||||||
setPattern(0);
|
// setPattern(0);
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
case InputCommand::Pattern2: {
|
// case InputCommand::Pattern2: {
|
||||||
setPattern(1);
|
// setPattern(1);
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
case InputCommand::Pattern3: {
|
// case InputCommand::Pattern3: {
|
||||||
setPattern(2);
|
// setPattern(2);
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
case InputCommand::Pattern4: {
|
// case InputCommand::Pattern4: {
|
||||||
setPattern(3);
|
// setPattern(3);
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
case InputCommand::Pattern5: {
|
// case InputCommand::Pattern5: {
|
||||||
setPattern(4);
|
// setPattern(4);
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
case InputCommand::Pattern6: {
|
// case InputCommand::Pattern6: {
|
||||||
setPattern(5);
|
// setPattern(5);
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
case InputCommand::Pattern7: {
|
// case InputCommand::Pattern7: {
|
||||||
setPattern(6);
|
// setPattern(6);
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
case InputCommand::Pattern8: {
|
// case InputCommand::Pattern8: {
|
||||||
setPattern(7);
|
// setPattern(7);
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
case InputCommand::Pattern9: {
|
// case InputCommand::Pattern9: {
|
||||||
setPattern(8);
|
// setPattern(8);
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
case InputCommand::Pattern10: {
|
// case InputCommand::Pattern10: {
|
||||||
setPattern(9);
|
// setPattern(9);
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
case InputCommand::Pattern11: {
|
// case InputCommand::Pattern11: {
|
||||||
setPattern(10);
|
// setPattern(10);
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
case InputCommand::Pattern12: {
|
// case InputCommand::Pattern12: {
|
||||||
setPattern(11);
|
// setPattern(11);
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
// custom color adjustment buttons
|
// // custom color adjustment buttons
|
||||||
|
//
|
||||||
case InputCommand::RedUp: {
|
// case InputCommand::RedUp: {
|
||||||
solidColor.red += 8;
|
// solidColor.red += 8;
|
||||||
setSolidColor(solidColor);
|
// setSolidColor(solidColor);
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
case InputCommand::RedDown: {
|
// case InputCommand::RedDown: {
|
||||||
solidColor.red -= 8;
|
// solidColor.red -= 8;
|
||||||
setSolidColor(solidColor);
|
// setSolidColor(solidColor);
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
case InputCommand::GreenUp: {
|
// case InputCommand::GreenUp: {
|
||||||
solidColor.green += 8;
|
// solidColor.green += 8;
|
||||||
setSolidColor(solidColor);
|
// setSolidColor(solidColor);
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
case InputCommand::GreenDown: {
|
// case InputCommand::GreenDown: {
|
||||||
solidColor.green -= 8;
|
// solidColor.green -= 8;
|
||||||
setSolidColor(solidColor);
|
// setSolidColor(solidColor);
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
case InputCommand::BlueUp: {
|
// case InputCommand::BlueUp: {
|
||||||
solidColor.blue += 8;
|
// solidColor.blue += 8;
|
||||||
setSolidColor(solidColor);
|
// setSolidColor(solidColor);
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
case InputCommand::BlueDown: {
|
// case InputCommand::BlueDown: {
|
||||||
solidColor.blue -= 8;
|
// solidColor.blue -= 8;
|
||||||
setSolidColor(solidColor);
|
// setSolidColor(solidColor);
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
// color buttons
|
// // color buttons
|
||||||
|
//
|
||||||
case InputCommand::Red: {
|
// case InputCommand::Red: {
|
||||||
setSolidColor(CRGB::Red);
|
// setSolidColor(CRGB::Red);
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
case InputCommand::RedOrange: {
|
// case InputCommand::RedOrange: {
|
||||||
setSolidColor(CRGB::OrangeRed);
|
// setSolidColor(CRGB::OrangeRed);
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
case InputCommand::Orange: {
|
// case InputCommand::Orange: {
|
||||||
setSolidColor(CRGB::Orange);
|
// setSolidColor(CRGB::Orange);
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
case InputCommand::YellowOrange: {
|
// case InputCommand::YellowOrange: {
|
||||||
setSolidColor(CRGB::Goldenrod);
|
// setSolidColor(CRGB::Goldenrod);
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
case InputCommand::Yellow: {
|
// case InputCommand::Yellow: {
|
||||||
setSolidColor(CRGB::Yellow);
|
// setSolidColor(CRGB::Yellow);
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
case InputCommand::Green: {
|
// case InputCommand::Green: {
|
||||||
setSolidColor(CRGB::Green);
|
// setSolidColor(CRGB::Green);
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
case InputCommand::Lime: {
|
// case InputCommand::Lime: {
|
||||||
setSolidColor(CRGB::Lime);
|
// setSolidColor(CRGB::Lime);
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
case InputCommand::Aqua: {
|
// case InputCommand::Aqua: {
|
||||||
setSolidColor(CRGB::Aqua);
|
// setSolidColor(CRGB::Aqua);
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
case InputCommand::Teal: {
|
// case InputCommand::Teal: {
|
||||||
setSolidColor(CRGB::Teal);
|
// setSolidColor(CRGB::Teal);
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
case InputCommand::Navy: {
|
// case InputCommand::Navy: {
|
||||||
setSolidColor(CRGB::Navy);
|
// setSolidColor(CRGB::Navy);
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
case InputCommand::Blue: {
|
// case InputCommand::Blue: {
|
||||||
setSolidColor(CRGB::Blue);
|
// setSolidColor(CRGB::Blue);
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
case InputCommand::RoyalBlue: {
|
// case InputCommand::RoyalBlue: {
|
||||||
setSolidColor(CRGB::RoyalBlue);
|
// setSolidColor(CRGB::RoyalBlue);
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
case InputCommand::Purple: {
|
// case InputCommand::Purple: {
|
||||||
setSolidColor(CRGB::Purple);
|
// setSolidColor(CRGB::Purple);
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
case InputCommand::Indigo: {
|
// case InputCommand::Indigo: {
|
||||||
setSolidColor(CRGB::Indigo);
|
// setSolidColor(CRGB::Indigo);
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
case InputCommand::Magenta: {
|
// case InputCommand::Magenta: {
|
||||||
setSolidColor(CRGB::Magenta);
|
// setSolidColor(CRGB::Magenta);
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
case InputCommand::White: {
|
// case InputCommand::White: {
|
||||||
setSolidColor(CRGB::White);
|
// setSolidColor(CRGB::White);
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
case InputCommand::Pink: {
|
// case InputCommand::Pink: {
|
||||||
setSolidColor(CRGB::Pink);
|
// setSolidColor(CRGB::Pink);
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
case InputCommand::LightPink: {
|
// case InputCommand::LightPink: {
|
||||||
setSolidColor(CRGB::LightPink);
|
// setSolidColor(CRGB::LightPink);
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
case InputCommand::BabyBlue: {
|
// case InputCommand::BabyBlue: {
|
||||||
setSolidColor(CRGB::CornflowerBlue);
|
// setSolidColor(CRGB::CornflowerBlue);
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
case InputCommand::LightBlue: {
|
// case InputCommand::LightBlue: {
|
||||||
setSolidColor(CRGB::LightBlue);
|
// setSolidColor(CRGB::LightBlue);
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|
||||||
void loadSettings()
|
void loadSettings()
|
||||||
{
|
{
|
||||||
@ -559,6 +606,12 @@ void loadSettings()
|
|||||||
{
|
{
|
||||||
solidColor = CRGB(r, g, b);
|
solidColor = CRGB(r, g, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
currentPaletteIndex = EEPROM.read(5);
|
||||||
|
if (currentPaletteIndex < 0)
|
||||||
|
currentPaletteIndex = 0;
|
||||||
|
else if (currentPaletteIndex >= paletteCount)
|
||||||
|
currentPaletteIndex = paletteCount - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendAll()
|
void sendAll()
|
||||||
@ -572,6 +625,10 @@ void sendAll()
|
|||||||
json += "\"index\":" + String(currentPatternIndex);
|
json += "\"index\":" + String(currentPatternIndex);
|
||||||
json += ",\"name\":\"" + patterns[currentPatternIndex].name + "\"}";
|
json += ",\"name\":\"" + patterns[currentPatternIndex].name + "\"}";
|
||||||
|
|
||||||
|
json += ",\"currentPalette\":{";
|
||||||
|
json += "\"index\":" + String(currentPaletteIndex);
|
||||||
|
json += ",\"name\":\"" + paletteNames[currentPaletteIndex] + "\"}";
|
||||||
|
|
||||||
json += ",\"solidColor\":{";
|
json += ",\"solidColor\":{";
|
||||||
json += "\"r\":" + String(solidColor.r);
|
json += "\"r\":" + String(solidColor.r);
|
||||||
json += ",\"g\":" + String(solidColor.g);
|
json += ",\"g\":" + String(solidColor.g);
|
||||||
@ -587,6 +644,15 @@ void sendAll()
|
|||||||
}
|
}
|
||||||
json += "]";
|
json += "]";
|
||||||
|
|
||||||
|
json += ",\"palettes\":[";
|
||||||
|
for (uint8_t i = 0; i < paletteCount; i++)
|
||||||
|
{
|
||||||
|
json += "\"" + paletteNames[i] + "\"";
|
||||||
|
if (i < paletteCount - 1)
|
||||||
|
json += ",";
|
||||||
|
}
|
||||||
|
json += "]";
|
||||||
|
|
||||||
json += "}";
|
json += "}";
|
||||||
|
|
||||||
server.send(200, "text/json", json);
|
server.send(200, "text/json", json);
|
||||||
@ -610,6 +676,16 @@ void sendPattern()
|
|||||||
json = String();
|
json = String();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sendPalette()
|
||||||
|
{
|
||||||
|
String json = "{";
|
||||||
|
json += "\"index\":" + String(currentPaletteIndex);
|
||||||
|
json += ",\"name\":\"" + paletteNames[currentPaletteIndex] + "\"";
|
||||||
|
json += "}";
|
||||||
|
server.send(200, "text/json", json);
|
||||||
|
json = String();
|
||||||
|
}
|
||||||
|
|
||||||
void sendBrightness()
|
void sendBrightness()
|
||||||
{
|
{
|
||||||
String json = String(brightness);
|
String json = String(brightness);
|
||||||
@ -663,8 +739,10 @@ void adjustPattern(bool up)
|
|||||||
if (currentPatternIndex >= patternCount)
|
if (currentPatternIndex >= patternCount)
|
||||||
currentPatternIndex = 0;
|
currentPatternIndex = 0;
|
||||||
|
|
||||||
|
if (!autoplayEnabled) {
|
||||||
EEPROM.write(1, currentPatternIndex);
|
EEPROM.write(1, currentPatternIndex);
|
||||||
EEPROM.commit();
|
EEPROM.commit();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setPattern(int value)
|
void setPattern(int value)
|
||||||
@ -677,8 +755,24 @@ void setPattern(int value)
|
|||||||
|
|
||||||
currentPatternIndex = value;
|
currentPatternIndex = value;
|
||||||
|
|
||||||
|
if (!autoplayEnabled) {
|
||||||
EEPROM.write(1, currentPatternIndex);
|
EEPROM.write(1, currentPatternIndex);
|
||||||
EEPROM.commit();
|
EEPROM.commit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setPalette(int value)
|
||||||
|
{
|
||||||
|
// don't wrap around at the ends
|
||||||
|
if (value < 0)
|
||||||
|
value = 0;
|
||||||
|
else if (value >= paletteCount)
|
||||||
|
value = paletteCount - 1;
|
||||||
|
|
||||||
|
currentPaletteIndex = value;
|
||||||
|
|
||||||
|
EEPROM.write(5, currentPaletteIndex);
|
||||||
|
EEPROM.commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
// adjust the brightness, and wrap around at the ends
|
// adjust the brightness, and wrap around at the ends
|
||||||
@ -748,7 +842,8 @@ void confetti()
|
|||||||
// random colored speckles that blink in and fade smoothly
|
// random colored speckles that blink in and fade smoothly
|
||||||
fadeToBlackBy( leds, NUM_LEDS, 10);
|
fadeToBlackBy( leds, NUM_LEDS, 10);
|
||||||
int pos = random16(NUM_LEDS);
|
int pos = random16(NUM_LEDS);
|
||||||
leds[pos] += CHSV( gHue + random8(64), 200, 255);
|
// leds[pos] += CHSV( gHue + random8(64), 200, 255);
|
||||||
|
leds[pos] += ColorFromPalette(palettes[currentPaletteIndex], gHue + random8(64));
|
||||||
}
|
}
|
||||||
|
|
||||||
void sinelon()
|
void sinelon()
|
||||||
@ -756,14 +851,15 @@ void sinelon()
|
|||||||
// a colored dot sweeping back and forth, with fading trails
|
// a colored dot sweeping back and forth, with fading trails
|
||||||
fadeToBlackBy( leds, NUM_LEDS, 20);
|
fadeToBlackBy( leds, NUM_LEDS, 20);
|
||||||
int pos = beatsin16(13, 0, NUM_LEDS - 1);
|
int pos = beatsin16(13, 0, NUM_LEDS - 1);
|
||||||
leds[pos] += CHSV( gHue, 255, 192);
|
// leds[pos] += CHSV( gHue, 255, 192);
|
||||||
|
leds[pos] += ColorFromPalette(palettes[currentPaletteIndex], gHue, 192);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bpm()
|
void bpm()
|
||||||
{
|
{
|
||||||
// colored stripes pulsing at a defined Beats-Per-Minute (BPM)
|
// colored stripes pulsing at a defined Beats-Per-Minute (BPM)
|
||||||
uint8_t BeatsPerMinute = 62;
|
uint8_t BeatsPerMinute = 62;
|
||||||
CRGBPalette16 palette = PartyColors_p;
|
CRGBPalette16 palette = palettes[currentPaletteIndex];
|
||||||
uint8_t beat = beatsin8( BeatsPerMinute, 64, 255);
|
uint8_t beat = beatsin8( BeatsPerMinute, 64, 255);
|
||||||
for ( int i = 0; i < NUM_LEDS; i++) { //9948
|
for ( int i = 0; i < NUM_LEDS; i++) { //9948
|
||||||
leds[i] = ColorFromPalette(palette, gHue + (i * 2), beat - gHue + (i * 10));
|
leds[i] = ColorFromPalette(palette, gHue + (i * 2), beat - gHue + (i * 10));
|
||||||
@ -777,7 +873,8 @@ void juggle()
|
|||||||
byte dothue = 0;
|
byte dothue = 0;
|
||||||
for ( int i = 0; i < 8; i++)
|
for ( int i = 0; i < 8; i++)
|
||||||
{
|
{
|
||||||
leds[beatsin16(i + 7, 0, NUM_LEDS)] |= CHSV(dothue, 200, 255);
|
// leds[beatsin16(i + 7, 0, NUM_LEDS)] |= CHSV(dothue, 200, 255);
|
||||||
|
leds[beatsin16(i + 7, 0, NUM_LEDS)] |= ColorFromPalette(palettes[currentPaletteIndex], dothue);
|
||||||
dothue += 32;
|
dothue += 32;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user