|
// From https://hackaday.io/project/176566-tiny-wifi-busy-light |
|
|
|
#include <Adafruit_NeoPixel.h> |
|
#include <ESP8266WiFi.h> |
|
|
|
char ssid[] = ""; // your network SSID (name) |
|
char pass[] = ""; // your network password |
|
|
|
IPAddress ip(192, 168, 2, 239); // If you want to have a fixed ip address, set it up here |
|
IPAddress gateway(192, 168, 2, 1); |
|
IPAddress subnet(255, 255, 255, 0); |
|
|
|
String CColor = ""; |
|
|
|
unsigned long ulReqcount; |
|
unsigned long ulReconncount; |
|
|
|
Adafruit_NeoPixel strip = Adafruit_NeoPixel(2, 15); |
|
WiFiServer server(80); |
|
|
|
void setup() |
|
{ |
|
// setup globals |
|
ulReqcount = 0; |
|
ulReconncount = 0; |
|
strip.begin(); |
|
strip.show(); |
|
|
|
|
|
//WiFi.config(ip, gateway, subnet); // comment this out if you want to get an ip address from dhcp-server |
|
|
|
WiFi.softAPdisconnect(true); |
|
WiFi.mode(WIFI_STA); |
|
WiFi.begin(ssid, pass); |
|
|
|
int itry = 0; |
|
while (WiFi.status() != WL_CONNECTED) { |
|
strip.begin(); |
|
for(int i = 0; i<12; i++) { |
|
strip.setPixelColor(i, 255, 255, 255); |
|
} |
|
strip.setBrightness(128), |
|
strip.show(); |
|
delay(500); |
|
strip.begin(); |
|
for(int i = 0; i<12; i++) { |
|
strip.setPixelColor(i, 0, 0, 0); |
|
} |
|
strip.setBrightness(128), |
|
strip.show(); |
|
delay(500); |
|
itry++; |
|
if(itry>=20) { |
|
for(int i = 0; i<12; i++) { |
|
strip.setPixelColor(i, 255, 255, 255); |
|
} |
|
while(true) { |
|
for(int i = 0; i<255; i++) { |
|
strip.begin(); |
|
strip.setBrightness(i), |
|
strip.show(); |
|
delay(100); |
|
} |
|
for(int i = 0; i<255; i++) { |
|
strip.begin(); |
|
strip.setBrightness(255-i), |
|
strip.show(); |
|
delay(100); |
|
} |
|
delay(1000); |
|
} |
|
} |
|
} |
|
server.begin(); |
|
} |
|
|
|
void changeColor(uint32_t c) { |
|
for(uint16_t i=0; i<strip.numPixels(); i++) { |
|
strip.setPixelColor(i, c); |
|
} |
|
strip.show(); |
|
} |
|
|
|
|
|
void colorWipe(uint32_t c, uint8_t wait) { |
|
for(uint16_t i=0; i<strip.numPixels(); i++) { |
|
strip.setPixelColor(i, c); |
|
delay(wait); |
|
strip.show(); |
|
delay(wait); |
|
} |
|
} |
|
|
|
void rainbow(uint8_t wait) { |
|
uint16_t i, j; |
|
|
|
for(j=0; j<256; j++) { |
|
for(i=0; i<strip.numPixels(); i++) { |
|
strip.setPixelColor(i, Wheel((i+j) & 255)); |
|
} |
|
strip.show(); |
|
delay(wait); |
|
} |
|
} |
|
|
|
void rainbowCycle(uint8_t wait) { |
|
uint16_t i, j; |
|
|
|
for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel |
|
for(i=0; i< strip.numPixels(); i++) { |
|
strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255)); |
|
} |
|
strip.show(); |
|
delay(wait); |
|
} |
|
} |
|
|
|
//Theatre-style crawling lights. |
|
void theaterChase(uint32_t c, uint8_t wait) { |
|
for (int j=0; j<10; j++) { //do 10 cycles of chasing |
|
for (int q=0; q < 3; q++) { |
|
for (uint16_t i=0; i < strip.numPixels(); i=i+3) { |
|
strip.setPixelColor(i+q, c); //turn every third pixel on |
|
} |
|
strip.show(); |
|
|
|
delay(wait); |
|
|
|
for (uint16_t i=0; i < strip.numPixels(); i=i+3) { |
|
strip.setPixelColor(i+q, 0); //turn every third pixel off |
|
} |
|
} |
|
} |
|
} |
|
|
|
//Theatre-style crawling lights with rainbow effect |
|
void theaterChaseRainbow(uint8_t wait) { |
|
for (int j=0; j < 256; j++) { // cycle all 256 colors in the wheel |
|
for (int q=0; q < 3; q++) { |
|
for (uint16_t i=0; i < strip.numPixels(); i=i+3) { |
|
strip.setPixelColor(i+q, Wheel( (i+j) % 255)); //turn every third pixel on |
|
} |
|
strip.show(); |
|
|
|
delay(wait); |
|
|
|
for (uint16_t i=0; i < strip.numPixels(); i=i+3) { |
|
strip.setPixelColor(i+q, 0); //turn every third pixel off |
|
} |
|
} |
|
} |
|
} |
|
|
|
// Input a value 0 to 255 to get a color value. |
|
// The colours are a transition r - g - b - back to r. |
|
uint32_t Wheel(byte WheelPos) { |
|
WheelPos = 255 - WheelPos; |
|
if(WheelPos < 85) { |
|
return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3); |
|
} |
|
if(WheelPos < 170) { |
|
WheelPos -= 85; |
|
return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3); |
|
} |
|
WheelPos -= 170; |
|
return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0); |
|
} |
|
|
|
void loop() |
|
{ |
|
WiFiClient client = server.available(); |
|
if (!client) { |
|
return; |
|
} |
|
unsigned long ultimeout = millis() + 250; |
|
while (!client.available() && (millis() < ultimeout)) { |
|
delay(1); |
|
} |
|
if (millis() > ultimeout) { |
|
return; |
|
} |
|
|
|
// Read the first line of the request |
|
String sRequest = client.readStringUntil('\r'); |
|
client.flush(); |
|
|
|
// stop client, if request is empty |
|
if (sRequest == "") { |
|
client.stop(); |
|
return; |
|
} |
|
|
|
// get path; end of path is either space or ? |
|
// Syntax is e.g. GET /?pin=MOTOR1STOP HTTP/1.1 |
|
String sPath = "", sParam = "", sCmd = ""; |
|
String sGetstart = "GET "; |
|
int iStart, iEndSpace, iEndQuest; |
|
iStart = sRequest.indexOf(sGetstart); |
|
if (iStart >= 0) { |
|
iStart += +sGetstart.length(); |
|
iEndSpace = sRequest.indexOf(" ", iStart); |
|
iEndQuest = sRequest.indexOf("?", iStart); |
|
|
|
// are there parameters? |
|
if (iEndSpace > 0) { |
|
if (iEndQuest > 0) { |
|
// there are parameters |
|
sPath = sRequest.substring(iStart, iEndQuest); |
|
sParam = sRequest.substring(iEndQuest, iEndSpace); |
|
} |
|
else { |
|
// NO parameters |
|
sPath = sRequest.substring(iStart, iEndSpace); |
|
} |
|
} |
|
} |
|
|
|
/////////////////////////////////////////////////////////////////////////////// |
|
// output parameters to serial, you may connect e.g. an Arduino and react on it |
|
/////////////////////////////////////////////////////////////////////////////// |
|
if (sParam.length() > 0) { |
|
int iEqu = sParam.indexOf("="); |
|
if (iEqu >= 0) { |
|
sCmd = sParam.substring(iEqu + 1, sParam.length()); |
|
} |
|
} |
|
|
|
/////////////////////////// |
|
// format the html response |
|
/////////////////////////// |
|
String sResponse, sHeader; |
|
|
|
//////////////////////////// |
|
// 404 for non-matching path |
|
//////////////////////////// |
|
if (sPath != "/") { |
|
sResponse = "<html><head><title>404 Not Found</title></head><body><h1>Not Found</h1><p>The requested URL was not found on this server.</p></body></html>"; |
|
|
|
sHeader = "HTTP/1.1 404 Not found\r\n"; |
|
sHeader += "Content-Length: "; |
|
sHeader += sResponse.length(); |
|
sHeader += "\r\n"; |
|
sHeader += "Content-Type: text/html\r\n"; |
|
sHeader += "Connection: close\r\n"; |
|
sHeader += "\r\n"; |
|
} |
|
/////////////////////// |
|
// format the html page |
|
/////////////////////// |
|
else { |
|
ulReqcount++; |
|
sResponse = "<html><head><title>BusyLight</title></head><body>"; |
|
sResponse += "<font color=\"#000000\"><body bgcolor=\"#000000\">"; |
|
sResponse += "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=yes\">"; |
|
sResponse += "<h1>Office BusyLight</h1>"; |
|
|
|
////////////////////// |
|
// react on parameters |
|
////////////////////// |
|
if (sCmd.length() > 0) { |
|
// write received command to html page |
|
sResponse += "Last Color Set:" + sCmd + "<BR>"; |
|
strip.begin(); |
|
// switch GPIO |
|
if (sCmd.indexOf("RED") >= 0) { |
|
for(int i = 0; i<12; i++) { |
|
strip.setPixelColor(i, 255, 0, 0); |
|
} |
|
strip.setBrightness(128), |
|
strip.show(); |
|
} |
|
else if (sCmd.indexOf("GREEN") >= 0) { |
|
for(int i = 0; i<12; i++) { |
|
strip.setPixelColor(i, 0, 255, 0); |
|
} |
|
strip.setBrightness(255), |
|
strip.show(); |
|
} |
|
else if (sCmd.indexOf("BLUE") >= 0) { |
|
for(int i = 0; i<12; i++) { |
|
strip.setPixelColor(i, 0, 0, 255); |
|
} |
|
strip.setBrightness(128), |
|
strip.show(); |
|
} |
|
else if (sCmd.indexOf("YELLOW") >= 0) { |
|
for(int i = 0; i<12; i++) { |
|
strip.setPixelColor(i, 255, 255, 0); |
|
} |
|
strip.setBrightness(128), |
|
strip.show(); |
|
} |
|
else if (sCmd.indexOf("WHITE") >= 0) { |
|
for(int i = 0; i<12; i++) { |
|
strip.setPixelColor(i, 255, 255, 255); |
|
} |
|
strip.setBrightness(128), |
|
strip.show(); |
|
} |
|
else if (sCmd.indexOf("PURPLE") >= 0) { |
|
for(int i = 0; i<12; i++) { |
|
strip.setPixelColor(i, 255, 0, 255); |
|
} |
|
strip.setBrightness(128), |
|
strip.show(); |
|
} |
|
else if (sCmd.indexOf("ORANGE") >= 0) { |
|
for(int i = 0; i<12; i++) { |
|
strip.setPixelColor(i, 255, 110, 0); |
|
} |
|
strip.setBrightness(128), |
|
strip.show(); |
|
} |
|
else if (sCmd.indexOf("CWR") >= 0) { |
|
colorWipe(strip.Color(255, 0, 0), 20); // Red |
|
} |
|
else if (sCmd.indexOf("CWG") >= 0) { |
|
colorWipe(strip.Color(0, 255, 0), 20); // Green |
|
} |
|
else if (sCmd.indexOf("CWB") >= 0) { |
|
colorWipe(strip.Color(0, 0, 255), 20); // Blue |
|
} |
|
else if (sCmd.indexOf("TCRB") >= 0) { |
|
theaterChaseRainbow(20); |
|
} |
|
else if (sCmd.indexOf("TCR") >= 0) { |
|
theaterChase(strip.Color(255, 0, 0), 20); // Red |
|
} |
|
else if (sCmd.indexOf("TCG") >= 0) { |
|
theaterChase(strip.Color(0, 255, 0), 20); // Green |
|
} |
|
else if (sCmd.indexOf("TCB") >= 0) { |
|
theaterChase(strip.Color(0, 0, 255), 20); // Blue |
|
} |
|
else if (sCmd.indexOf("RBC") >= 0) { |
|
rainbowCycle(20); |
|
} |
|
else if (sCmd.indexOf("RBOW") >= 0) { |
|
rainbow(20); |
|
} |
|
else if (sCmd.indexOf("CYAN") >= 0) { |
|
for(int i = 0; i<12; i++) { |
|
strip.setPixelColor(i, 0, 255, 255); |
|
} |
|
strip.setBrightness(128), |
|
strip.show(); |
|
} |
|
else if (sCmd.indexOf("RAINBOW") >= 0) { |
|
strip.setPixelColor(0, 255, 0, 0); |
|
strip.setPixelColor(1, 255, 0, 128); |
|
strip.setPixelColor(2, 255, 0, 255); |
|
strip.setPixelColor(3, 0, 0, 255); |
|
strip.setPixelColor(4, 0, 128, 255); |
|
strip.setPixelColor(5, 0, 255, 0); |
|
strip.setPixelColor(6, 0, 255, 128); |
|
strip.setPixelColor(7, 128, 255, 0); |
|
strip.setPixelColor(8, 255, 255, 0); |
|
strip.setPixelColor(9, 0, 255, 255); |
|
strip.setPixelColor(10, 0, 255, 255); |
|
strip.setPixelColor(10, 0, 255, 255); |
|
strip.setPixelColor(11, 0, 255, 255); |
|
strip.setBrightness(128), |
|
strip.show(); |
|
} |
|
else if (sCmd.indexOf("OFF") >= 0) { |
|
for(int i = 0; i<12; i++) { |
|
strip.setPixelColor(i, 0, 0, 0); |
|
} |
|
strip.setBrightness(128), |
|
strip.show(); |
|
} |
|
} |
|
sResponse += "</body></html>"; |
|
|
|
sHeader = "HTTP/1.1 200 OK\r\n"; |
|
sHeader += "Content-Length: "; |
|
sHeader += sResponse.length(); |
|
sHeader += "\r\n"; |
|
sHeader += "Content-Type: text/html\r\n"; |
|
sHeader += "Connection: close\r\n"; |
|
sHeader += "\r\n"; |
|
} |
|
|
|
// Send the response to the client |
|
client.print(sHeader); |
|
client.print(sResponse); |
|
|
|
// and stop the client |
|
client.stop(); |
|
} |
Just stumpled over this gist, via your comment on https://hackaday.io/project/180751-5-wifi-busy-light-2021-had-prize-entry
If been looking for a the same use-case but for Win10 environments. Do you know if there is anything similar?