forked from jasoncoon/esp32-fastled-webserver
-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathesp32-fastled-webserver.ino
269 lines (210 loc) · 8.11 KB
/
esp32-fastled-webserver.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
/*
ESP32 FastLED WebServer: https://github.com/jasoncoon/esp32-fastled-webserver
Copyright (C) 2017 Jason Coon
Built upon the amazing FastLED work of Daniel Garcia and Mark Kriegsman:
https://github.com/FastLED/FastLED
ESP32 support provided by the hard work of Sam Guyer:
https://github.com/samguyer/FastLED
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
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <FastLED.h>
#include <WiFi.h>
#include <ESP8266WebServer.h>
#include <FS.h>
#include <SPIFFS.h>
#include <EEPROM.h>
#if defined(FASTLED_VERSION) && (FASTLED_VERSION < 3001008)
#warning "Requires FastLED 3.1.8 or later; check github for latest code."
#endif
WebServer webServer(80);
const int led = 5;
uint8_t autoplay = 0;
uint8_t autoplayDuration = 10;
unsigned long autoPlayTimeout = 0;
uint8_t currentPatternIndex = 0; // Index number of which pattern is current
uint8_t gHue = 0; // rotating "base color" used by many of the patterns
uint8_t power = 1;
uint8_t brightness = 8;
uint8_t speed = 30;
// COOLING: How much does the air cool as it rises?
// Less cooling = taller flames. More cooling = shorter flames.
// Default 50, suggested range 20-100
uint8_t cooling = 50;
// SPARKING: What chance (out of 255) is there that a new spark will be lit?
// Higher chance = more roaring fire. Lower chance = more flickery fire.
// Default 120, suggested range 50-200.
uint8_t sparking = 120;
CRGB solidColor = CRGB::Blue;
uint8_t cyclePalettes = 0;
uint8_t paletteDuration = 10;
uint8_t currentPaletteIndex = 0;
unsigned long paletteTimeout = 0;
#define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0]))
#define DATA_PIN 12 // pins tested so far on the Feather ESP32: 13, 12, 27, 33, 15, 32, 14, SCL
//#define CLK_PIN 4
#define LED_TYPE WS2812B
#define COLOR_ORDER RGB
#define NUM_STRIPS 8
#define NUM_LEDS_PER_STRIP 100
#define NUM_LEDS NUM_LEDS_PER_STRIP * NUM_STRIPS
CRGB leds[NUM_LEDS];
#define MILLI_AMPS 4000 // IMPORTANT: set the max milli-Amps of your power supply (4A = 4000mA)
#define FRAMES_PER_SECOND 120
// -- The core to run FastLED.show()
#define FASTLED_SHOW_CORE 0
#include "patterns.h"
#include "field.h"
#include "fields.h"
#include "secrets.h"
#include "wifi.h"
#include "web.h"
// wifi ssid and password should be added to a file in the sketch named secrets.h
// the secrets.h file should be added to the .gitignore file and never committed or
// pushed to public source control (GitHub).
// const char* ssid = "........";
// const char* password = "........";
// -- Task handles for use in the notifications
static TaskHandle_t FastLEDshowTaskHandle = 0;
static TaskHandle_t userTaskHandle = 0;
/** show() for ESP32
Call this function instead of FastLED.show(). It signals core 0 to issue a show,
then waits for a notification that it is done.
*/
void FastLEDshowESP32()
{
if (userTaskHandle == 0) {
// -- Store the handle of the current task, so that the show task can
// notify it when it's done
userTaskHandle = xTaskGetCurrentTaskHandle();
// -- Trigger the show task
xTaskNotifyGive(FastLEDshowTaskHandle);
// -- Wait to be notified that it's done
const TickType_t xMaxBlockTime = pdMS_TO_TICKS( 200 );
ulTaskNotifyTake(pdTRUE, xMaxBlockTime);
userTaskHandle = 0;
}
}
/** show Task
This function runs on core 0 and just waits for requests to call FastLED.show()
*/
void FastLEDshowTask(void *pvParameters)
{
// -- Run forever...
for (;;) {
// -- Wait for the trigger
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
// -- Do the show (synchronously)
FastLED.show();
// -- Notify the calling task
xTaskNotifyGive(userTaskHandle);
}
}
void listDir(fs::FS &fs, const char * dirname, uint8_t levels) {
Serial.printf("Listing directory: %s\n", dirname);
File root = fs.open(dirname);
if (!root) {
Serial.println("Failed to open directory");
return;
}
if (!root.isDirectory()) {
Serial.println("Not a directory");
return;
}
File file = root.openNextFile();
while (file) {
if (file.isDirectory()) {
Serial.print(" DIR : ");
Serial.println(file.name());
if (levels) {
listDir(fs, file.name(), levels - 1);
}
} else {
Serial.print(" FILE: ");
Serial.print(file.name());
Serial.print(" SIZE: ");
Serial.println(file.size());
}
file = root.openNextFile();
}
}
void setup() {
pinMode(led, OUTPUT);
digitalWrite(led, 1);
// delay(3000); // 3 second delay for recovery
Serial.begin(115200);
SPIFFS.begin();
listDir(SPIFFS, "/", 1);
// loadFieldsFromEEPROM(fields, fieldCount);
setupWifi();
setupWeb();
// three-wire LEDs (WS2811, WS2812, NeoPixel)
// FastLED.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
// four-wire LEDs (APA102, DotStar)
//FastLED.addLeds<LED_TYPE,DATA_PIN,CLK_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
// Parallel output: 13, 12, 27, 33, 15, 32, 14, SCL
FastLED.addLeds<LED_TYPE, 13, COLOR_ORDER>(leds, 0, NUM_LEDS_PER_STRIP).setCorrection(TypicalLEDStrip);
FastLED.addLeds<LED_TYPE, 12, COLOR_ORDER>(leds, NUM_LEDS_PER_STRIP, NUM_LEDS_PER_STRIP).setCorrection(TypicalLEDStrip);
FastLED.addLeds<LED_TYPE, 27, COLOR_ORDER>(leds, 2 * NUM_LEDS_PER_STRIP, NUM_LEDS_PER_STRIP).setCorrection(TypicalLEDStrip);
FastLED.addLeds<LED_TYPE, 33, COLOR_ORDER>(leds, 3 * NUM_LEDS_PER_STRIP, NUM_LEDS_PER_STRIP).setCorrection(TypicalLEDStrip);
FastLED.addLeds<LED_TYPE, 15, COLOR_ORDER>(leds, 4 * NUM_LEDS_PER_STRIP, NUM_LEDS_PER_STRIP).setCorrection(TypicalLEDStrip);
FastLED.addLeds<LED_TYPE, 32, COLOR_ORDER>(leds, 5 * NUM_LEDS_PER_STRIP, NUM_LEDS_PER_STRIP).setCorrection(TypicalLEDStrip);
FastLED.addLeds<LED_TYPE, 14, COLOR_ORDER>(leds, 6 * NUM_LEDS_PER_STRIP, NUM_LEDS_PER_STRIP).setCorrection(TypicalLEDStrip);
FastLED.addLeds<LED_TYPE, SCL, COLOR_ORDER>(leds, 7 * NUM_LEDS_PER_STRIP, NUM_LEDS_PER_STRIP).setCorrection(TypicalLEDStrip);
FastLED.setMaxPowerInVoltsAndMilliamps(5, MILLI_AMPS);
// set master brightness control
FastLED.setBrightness(brightness);
int core = xPortGetCoreID();
Serial.print("Main code running on core ");
Serial.println(core);
// -- Create the FastLED show task
xTaskCreatePinnedToCore(FastLEDshowTask, "FastLEDshowTask", 2048, NULL, 2, &FastLEDshowTaskHandle, FASTLED_SHOW_CORE);
autoPlayTimeout = millis() + (autoplayDuration * 1000);
}
void loop()
{
handleWeb();
if (power == 0) {
fill_solid(leds, NUM_LEDS, CRGB::Black);
}
else {
// Call the current pattern function once, updating the 'leds' array
patterns[currentPatternIndex].pattern();
EVERY_N_MILLISECONDS(40) {
// slowly blend the current palette to the next
nblendPaletteTowardPalette(currentPalette, targetPalette, 8);
gHue++; // slowly cycle the "base color" through the rainbow
}
if (autoplay == 1 && (millis() > autoPlayTimeout)) {
nextPattern();
autoPlayTimeout = millis() + (autoplayDuration * 1000);
}
if (cyclePalettes == 1 && (millis() > paletteTimeout)) {
nextPalette();
paletteTimeout = millis() + (paletteDuration * 1000);
}
}
// send the 'leds' array out to the actual LED strip
FastLEDshowESP32();
// FastLED.show();
// insert a delay to keep the framerate modest
FastLED.delay(1000 / FRAMES_PER_SECOND);
}
void nextPattern()
{
// add one to the current pattern number, and wrap around at the end
currentPatternIndex = (currentPatternIndex + 1) % patternCount;
}
void nextPalette()
{
currentPaletteIndex = (currentPaletteIndex + 1) % paletteCount;
targetPalette = palettes[currentPaletteIndex];
}