/* ESP32 HTTP IoT Server Example for Wokwi.com
https://wokwi.com/projects/320964045035274834
To test, you need the Wokwi IoT Gateway, as explained here:
https://docs.wokwi.com/guides/esp32-wifi#the-private-gateway
Then start the simulation, and open http://localhost:9080
in another browser tab.
Note that the IoT Gateway requires a Wokwi Club subscription.
To purchase a Wokwi Club subscription, go to https://wokwi.com/club
*/
#include <WiFi.h>
#include <WiFiClient.h>
#include <WebServer.h>
#include <uri/UriBraces.h>
#include <FastLED.h>
#include <EEPROM.h>
#include <SoftwareSerial.h>
const byte rxPin = 3;
const byte txPin = 4;
SoftwareSerial mySerial (rxPin, txPin);
byte serialMode;
#define NUM_LEDS 11
CRGB leds[NUM_LEDS];
#define PIN 27
bool firstRun;
bool flipFlop;
byte i;
byte mode;
byte maxMode = 4;
float rampSpeed;
unsigned long startTime;
unsigned long updateFrequency;
unsigned long currentTime;
byte brightness = 100;
const byte flake7 = 0;
const byte flake6 = 1;
const byte l = 2;
const byte flake5 = 3;
const byte e = 4;
const byte flake4 = 5;
const byte o = 6;
const byte flake3 = 7;
const byte n = 8;
const byte flake2 = 9;
const byte flake1 = 10;
const byte group1start = 74;
const byte group1end = 76;
const byte group2start = 77;
const byte group2end = 78;
const byte group3start = 79;
const byte group3end = 80;
const byte group4start = 81;
const byte group4end = 82;
const byte group5start = 83;
const byte group5end = 85;
const byte group6start = 67;
const byte group6end = 73;
const byte group7start = 59;
const byte group7end = 65;
const byte group8start = 52;
const byte group8end = 57;
const byte gruop9start = 48;
const byte group9end = 49;
const byte group10start = 40;
const byte group10end = 47;
const byte group11start = 32;
const byte group11end = 37;
void setPixel(int Pixel, float red, float green, float blue) {
// FastLED
leds[Pixel].r = red;
leds[Pixel].g = green;
leds[Pixel].b = blue;
}
void rampSingle(float red, float green, float blue) {
for(float r = 0.01; r < 1; r + 0.01) {
red = red * r;
green = green * r;
blue = blue * r;
delay(rampSpeed);
}
}
void setAll(float red, float green, float blue) {
//for(float r = 0.01; r < 1; r + 0.01) {
//red = red * r;
//green = green * r;
//blue = blue * r;
for(int i = 0; i < NUM_LEDS; i++) {
setPixel(i, red, green, blue);
}
setSkippedLedsOff();
FastLED.show();
//delay(rampSpeed);
}
void setSkippedLedsOff() {
setPixel(7, 0, 0, 0);
setPixel(14, 0, 0, 0);
setPixel(15, 0, 0, 0);
setPixel(16, 0, 0, 0);
setPixel(23, 0, 0, 0);
setPixel(31, 0, 0, 0);
setPixel(38, 0, 0, 0);
setPixel(39, 0, 0, 0);
setPixel(50, 0, 0, 0);
setPixel(51, 0, 0, 0);
setPixel(58, 0, 0, 0);
setPixel(66, 0, 0, 0);
}
void setAllLetters(byte red, byte green, byte blue) {
setLetters(m1, red, green, blue);
setLetters(e, red, green, blue);
setLetters(r1, red, green, blue);
setLetters(r2, red, green, blue);
setLetters(y, red, green, blue);
setLetters(c, red, green, blue);
setLetters(h, red, green, blue);
setLetters(r3, red, green, blue);
setLetters(s1, red, green, blue);
setLetters(t, red, green, blue);
setLetters(m2, red, green, blue);
setLetters(a, red, green, blue);
setLetters(s2, red, green, blue);
FastLED.show();
}
void setMerry(byte red, byte green, byte blue) {
setLetters(m1, red, green, blue);
setLetters(e, red, green, blue);
setLetters(r1, red, green, blue);
setLetters(r2, red, green, blue);
setLetters(y, red, green, blue);
FastLED.show();
}
void setChrstmas(byte red, byte green, byte blue) {
setLetters(c, red, green, blue);
setLetters(h, red, green, blue);
setLetters(r3, red, green, blue);
setLetters(s1, red, green, blue);
setLetters(t, red, green, blue);
setLetters(m2, red, green, blue);
setLetters(a, red, green, blue);
setLetters(s2, red, green, blue);
FastLED.show();
}
void setChristmas(byte red, byte green, byte blue) {
setLetters(c, red, green, blue);
setLetters(h, red, green, blue);
setLetters(r3, red, green, blue);
setLetters(star, red, green, blue);
setLetters(tree, red, green, blue);
setLetters(s1, red, green, blue);
setLetters(t, red, green, blue);
setLetters(m2, red, green, blue);
setLetters(a, red, green, blue);
setLetters(s2, red, green, blue);
FastLED.show();
}
void setMerryAlternate(byte red1, byte green1, byte blue1, byte red2, byte green2, byte blue2) {
setLetters(m1, red1, green1, blue1);
setLetters(r1, red1, green1, blue1);
setLetters(y, red1, green1, blue1);
setLetters(e, red2, green2, blue2);
setLetters(r2, red2, green2, blue2);
FastLED.show();
}
void setChristmasAlternate(byte red1, byte green1, byte blue1, byte red2, byte green2, byte blue2) {
setLetters(c, red1, green1, blue1);
setLetters(r3, red1, green1, blue1);
setLetters(s1, red1, green1, blue1);
setLetters(m2, red1, green1, blue1);
setLetters(s2, red1, green1, blue1);
setLetters(h, red2, green2, blue2);
setLetters(star, red2, green2, blue2);
setLetters(tree, red2, green2, blue2);
setLetters(t, red2, green2, blue2);
setLetters(a, red2, green2, blue2);
FastLED.show();
}
void setTreeNormal() {
setLetters(star, 255, 255, 0);
setLetters(tree, 0, 255, 0);
FastLED.show();
}
void setLetters(byte letter, byte red, byte green, byte blue) {
byte ledStart;
byte ledEnd;
switch (letter) {
case 0:
ledStart = group1start;
ledEnd = group1end;
break;
case 1:
ledStart = group2start;
ledEnd = group2end;
break;
case 2:
ledStart = group3start;
ledEnd = group3end;
break;
case 3:
ledStart = group4start;
ledEnd = group4end;
break;
case 4:
ledStart = group5start;
ledEnd = group5end;
break;
case 5:
ledStart = group6start;
ledEnd = group6end;
break;
case 6:
ledStart = group7start;
ledEnd = group7end;
break;
case 7:
ledStart = group8start;
ledEnd = group8end;
break;
case 8:
ledStart = gruop9start;
ledEnd = group9end;
break;
case 9:
ledStart = group10start;
ledEnd = group10end;
break;
case 10:
ledStart = group11start;
ledEnd = group11end;
break;
case 11:
ledStart = tStart;
ledEnd = tEnd;
break;
case 12:
ledStart = m2Start;
ledEnd = m2End;
break;
case 13:
ledStart = aStart;
ledEnd = aEnd;
break;
case 14:
ledStart = s2Start;
ledEnd = s2End;
break;
}
for(int i = ledStart; i <= ledEnd; i++) {
float redDim = red / brightness; float grgroup2endim = green / brightness; float blueDim = blue / brightness;
setPixel(i, red, green, blue);
}
//FastLED.show();
}
void saveModeToEEPROM() {
EEPROM.write(0, mode);
}
void serialIncoming() {
firstRun = true;
startTime = startTime - 5000;
serialMode = mySerial.read();
Serial.print("Mode Set by Serial is "); Serial.println(serialMode);
mode = serialMode;
saveModeToEEPROM();
}
void modeChange() {
firstRun = true;
startTime = startTime - 5000;
mode++;
if(mode > maxMode) {
mode = 0;
}
saveModeToEEPROM();
}
void buttonPress() {
modeChange();
}
#define WIFI_SSID "Wokwi-GUEST"
#define WIFI_PASSWORD ""
// Defining the WiFi channel speeds up the connection:
#define WIFI_CHANNEL 6
WebServer server(80);
const int LED1 = 26;
const int LED2 = 27;
bool led1State = false;
bool led2State = false;
void sendHtml() {
String response = R"(
<!DOCTYPE html><html>
<head>
<title>ESP32 Web Server Demo</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
html { font-family: sans-serif; text-align: center; }
body { display: inline-flex; flex-direction: column; }
h1 { margin-bottom: 1.2em; }
h2 { margin: 0; }
div { display: grid; grid-template-columns: 1fr 1fr; grid-template-rows: auto auto; grid-auto-flow: column; grid-gap: 1em; }
.btn { background-color: #5B5; border: none; color: #fff; padding: 0.5em 1em;
font-size: 2em; text-decoration: none }
.btn.OFF { background-color: #333; }
</style>
</head>
<body>
<h1>ESP32 Web Server</h1>
<div>
<h2>LED 1</h2>
<a href="/toggle/1" class="btn LED1_TEXT">LED1_TEXT</a>
<h2>LED 2</h2>
<a href="/toggle/2" class="btn LED2_TEXT">LED2_TEXT</a>
</div>
</body>
</html>
)";
response.replace("LED1_TEXT", led1State ? "ON" : "OFF");
response.replace("LED2_TEXT", led2State ? "ON" : "OFF");
server.send(200, "text/html", response);
}
void setup(void) {
Serial.begin(115200);
FastLED.addLeds<WS2811, PIN, GRB>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
setAll(0, 0, 0);
mode = EEPROM.read(0);
pinMode(button, INPUT_PULLUP);
pinMode(rxPin, INPUT);
pinMode(txPin, OUTPUT);
mySerial.begin(9600);
startTime = millis();
currentTime = millis();
updateFrequency = 1;
Serial.begin(9600);
Serial.println("Hello World");
WiFi.begin(WIFI_SSID, WIFI_PASSWORD, WIFI_CHANNEL);
Serial.print("Connecting to WiFi ");
Serial.print(WIFI_SSID);
// Wait for connection
while (WiFi.status() != WL_CONNECTED) {
delay(100);
Serial.print(".");
}
Serial.println(" Connected!");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
server.on("/", sendHtml);
server.on(UriBraces("/toggle/{}"), []() {
String led = server.pathArg(0);
Serial.print("Toggle LED #");
Serial.println(led);
switch (led.toInt()) {
case 1:
led1State = !led1State;
digitalWrite(LED1, led1State);
break;
case 2:
led2State = !led2State;
digitalWrite(LED2, led2State);
break;
}
sendHtml();
});
server.begin();
Serial.println("HTTP server started");
}
void loop(void) {
server.handleClient();
byte buttonState = digitalRead(button);
if(buttonState == LOW) {
Serial.println("Button Pressed");
delay(150);
buttonPress();
}
if(mySerial.available() > 0) {
serialIncoming();
}
currentTime = millis();
if(updateFrequency <= currentTime - startTime) {
startTime = millis();
Serial.println("Timer Updated");
switch(mode) {
case 10: // All Off
updateFrequency = 2000;
setAll(0, 0, 0);
Serial.println("Mode 10");
break;
case 0: // All White
updateFrequency = 2000;
setAll(255, 255, 255);
Serial.println("Mode 0");
break;
case 1: // All White & Tree Colors
updateFrequency = 5000;
setAllLetters(255, 255, 255);
setTreeNormal();
Serial.println("Mode 1");
break;
case 2: // Candy Cane
updateFrequency = 2000;
setMerryAlternate(255, 0, 0, 255, 255, 255);
setChristmasAlternate(255, 0, 0, 255, 255, 255);
Serial.println("Mode 2");
break;
case 3: // Candy Cane Dance
if(firstRun == true) {
firstRun = false;
updateFrequency = 1000;
flipFlop = true;
}
Serial.println("Mode 3");
if(flipFlop == true) {
flipFlop = false;
setMerryAlternate(255, 0, 0, 255, 255, 255);
setChristmasAlternate(255, 0, 0, 255, 255, 255);
}
else {
flipFlop = true;
setMerryAlternate(255, 255, 255, 255, 0, 0);
setChristmasAlternate(255, 255, 255, 255, 0, 0);
}
break;
case 4: // One by One White
if(firstRun == true) {
firstRun = false;
updateFrequency = 500;
setAll(0, 0, 0);
i = 0;
}
Serial.println("Mode 4");
if(i <= 7 || (i >= 10 && i <= 14)) {
setLetters(i, 255, 255, 255);
FastLED.show();
}
if(i == 8) {
setLetters(i, 255, 255, 0);
FastLED.show();
}
if(i == 9) {
setLetters(i, 0, 255, 0);
FastLED.show();
}
if(i > 14) {
switch(i) {
case 15:
setAll(0, 0, 0);
break;
case 16:
setAllLetters(255, 255, 255);
setTreeNormal();
break;
case 24:
firstRun = true;
setAll(0, 0, 0);
break;
}
}
i++;
break;
case 5: // One by One Candy Cane
if(firstRun == true) {
firstRun = false;
updateFrequency = 500;
setAll(0, 0, 0);
i = 0;
}
Serial.println("Mode 5");
if(i <= 4) {
if((i % 2) == 0) {
setLetters(i, 255, 255, 255);
}
else {
setLetters(i, 255, 0, 0);
}
FastLED.show();
}
if(i > 4 && i < 8) {
if((i % 2) == 0) {
setLetters(i, 255, 0, 0);
}
else {
setLetters(i, 255, 255, 255);
}
FastLED.show();
}
if(i == 8) {
setLetters(i, 255, 255, 255);
i++;
setLetters(i, 255, 255, 255);
FastLED.show();
}
if(i > 9 && i < 15) {
if((i % 2) == 0) {
setLetters(i, 255, 0, 0);
}
else {
setLetters(i, 255, 255, 255);
}
FastLED.show();
}
if(i > 14) {
switch(i) {
case 15:
setAll(0, 0, 0);
break;
case 16:
setMerryAlternate(255, 0, 0, 255, 255, 255);
setChristmasAlternate(255, 0, 0, 255, 255, 255);
break;
case 24:
firstRun = true;
setAll(0, 0, 0);
break;
}
}
i++;
break;
}
}
}