Compare commits
4 Commits
ultim8x8
...
wifi-exper
Author | SHA1 | Date | |
---|---|---|---|
a402019e4d | |||
1d4f7e74de | |||
545acb7144 | |||
02e5ae137f |
48
README.md
48
README.md
@ -6,14 +6,38 @@ Control an addressable LED strip with an ESP8266 via a web browser or infrared r
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
[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
|
||||
--------
|
||||
* 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 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 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 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 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
|
||||
-----------
|
||||
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 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.
|
||||
|
||||
* [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](https://github.com/esp8266/Arduino/blob/master/doc/filesystem.md#uploading-files-to-file-system).
|
||||
|
||||
With ESP8266FS installed run the sketch and then upload the web app using `ESP8266 Sketch Data Upload` command in the Arduino Tools menu.
|
||||
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
|
||||
-----------
|
||||
@ -61,7 +95,7 @@ The firmware implements basic [RESTful web services](https://en.wikipedia.org/wi
|
||||
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 HUZZAH ESP8266 Breakout]:https://www.adafruit.com/products/2471
|
||||
|
157
WiFi.h
Normal file
157
WiFi.h
Normal file
@ -0,0 +1,157 @@
|
||||
//#include <DNSServer.h>
|
||||
|
||||
//DNSServer dnsServer;
|
||||
|
||||
//const byte DNS_PORT = 53;
|
||||
|
||||
// AP mode password
|
||||
const char WiFiAPPSK[] = "";
|
||||
|
||||
// Wi-Fi network to connect to (leave blank to connect to saved network, or to start in AP mode)
|
||||
const char* ssid = "";
|
||||
const char* password = "";
|
||||
|
||||
#define HOSTNAME "ESP8266-" ///< Hostname. The initializeWiFi function adds the Chip ID at the end.
|
||||
|
||||
#define DEBUG_WIFI 1
|
||||
|
||||
WiFiMode mode = WIFI_STA; // connect to existing Wi-Fi network
|
||||
//WiFiMode mode = WIFI_AP; // act as an Access Point, creating a new Wi-Fi network
|
||||
//WiFiMode mode = WIFI_AP_STA; // act as both a client and Access Point (mesh mode)
|
||||
|
||||
template <typename Generic>
|
||||
void debugPrint(Generic text) {
|
||||
if (DEBUG_WIFI) {
|
||||
Serial.print(text);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Generic>
|
||||
void debugPrintln(Generic text) {
|
||||
if (DEBUG_WIFI) {
|
||||
Serial.println(text);
|
||||
}
|
||||
}
|
||||
|
||||
String getWiFiJson() {
|
||||
String hostname = String(HOSTNAME);
|
||||
hostname += String(ESP.getChipId(), HEX);
|
||||
|
||||
String json = "{";
|
||||
|
||||
json += "\"status\":\"" + String(WiFi.status()) + "\"";
|
||||
json += ",\"localIP\":\"" + WiFi.localIP().toString() + "\"";
|
||||
json += ",\"softAPIP\":\"" + WiFi.softAPIP().toString() + "\"";
|
||||
json += ",\"hostname\":\"" + hostname + "\"";
|
||||
json += ",\"ssid\":\"" + WiFi.SSID() + "\"";
|
||||
json += ",\"rssi\":\"" + String(WiFi.RSSI()) + "\"";
|
||||
|
||||
json += ",\"networks\":[";
|
||||
byte ssidCount = WiFi.scanNetworks();
|
||||
for (byte i = 0; i < ssidCount; i++) {
|
||||
if (i > 0)
|
||||
json += ",";
|
||||
|
||||
json += "{\"name\":\"" + WiFi.SSID(i) + "\",\"rssi\":\"" + String(WiFi.RSSI(i)) + "\"}";
|
||||
}
|
||||
|
||||
json += "]";
|
||||
|
||||
json += "}";
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
void initializeWiFi() {
|
||||
// Set Hostname.
|
||||
String hostname = String(HOSTNAME);
|
||||
hostname += String(ESP.getChipId(), HEX);
|
||||
WiFi.hostname(hostname);
|
||||
|
||||
// Print hostname.
|
||||
Serial.println("Hostname: " + hostname);
|
||||
|
||||
char hostnameChar[hostname.length() + 1];
|
||||
memset(hostnameChar, 0, hostname.length() + 1);
|
||||
|
||||
for (uint8_t i = 0; i < hostname.length(); i++)
|
||||
hostnameChar[i] = hostname.charAt(i);
|
||||
|
||||
// MDNS.begin(hostnameChar);
|
||||
|
||||
// Add service to MDNS-SD
|
||||
// MDNS.addService("http", "tcp", 80);
|
||||
|
||||
// attempt to connect; should it fail, fall back to AP mode
|
||||
// WiFi.mode(WIFI_STA);
|
||||
|
||||
String stored_ssid = WiFi.SSID();
|
||||
|
||||
if (ssid != NULL && password != NULL &&
|
||||
ssid != "" && password != "") {
|
||||
debugPrint("WiFi mode: ");
|
||||
debugPrintln(WIFI_STA);
|
||||
WiFi.mode(WIFI_STA);
|
||||
|
||||
debugPrint("Connecting to hard-coded SSID: ");
|
||||
debugPrintln(stored_ssid);
|
||||
WiFi.begin(ssid, password);
|
||||
}
|
||||
else if (stored_ssid != NULL && stored_ssid != "") {
|
||||
debugPrint("WiFi mode: ");
|
||||
debugPrintln(WIFI_STA);
|
||||
WiFi.mode(WIFI_STA);
|
||||
|
||||
debugPrint("Connecting to stored SSID: ");
|
||||
debugPrintln(stored_ssid);
|
||||
WiFi.begin();
|
||||
}
|
||||
else {
|
||||
debugPrintln("No stored SSID");
|
||||
debugPrint("Starting soft AP: ");
|
||||
debugPrintln(hostnameChar);
|
||||
|
||||
WiFi.mode(WIFI_AP);
|
||||
|
||||
if (WiFiAPPSK != NULL) {
|
||||
debugPrint(WiFi.softAP(hostnameChar, WiFiAPPSK) ? "ready" : "failed");
|
||||
} else {
|
||||
debugPrint(WiFi.softAP(hostnameChar) ? "ready" : "failed");
|
||||
}
|
||||
|
||||
debugPrint("Connect to Wi-Fi access point: ");
|
||||
debugPrintln(hostnameChar);
|
||||
|
||||
delay(500); // Without delay I've seen the IP address blank
|
||||
debugPrint("AP IP address: ");
|
||||
debugPrintln(WiFi.softAPIP());
|
||||
|
||||
// dnsServer.setErrorReplyCode(DNSReplyCode::NoError);
|
||||
// dnsServer.start(DNS_PORT, "*", WiFi.softAPIP());
|
||||
}
|
||||
|
||||
webServer.on("/wifi", HTTP_POST, []() {
|
||||
String ssid = webServer.arg("ssid");
|
||||
String password = webServer.arg("password");
|
||||
|
||||
char ssidChars[50];
|
||||
ssid.toCharArray(ssidChars, 50);
|
||||
|
||||
char passwordChars[50];
|
||||
password.toCharArray(passwordChars, 50);
|
||||
|
||||
debugPrint("Connecting to new SSID: ");
|
||||
debugPrintln(ssid);
|
||||
|
||||
WiFi.begin(ssidChars, passwordChars);
|
||||
|
||||
webServer.sendHeader("Location", "/wifi.htm");
|
||||
webServer.send(303);
|
||||
});
|
||||
|
||||
webServer.on("/wifi", HTTP_GET, []() {
|
||||
String json = getWiFiJson();
|
||||
webServer.send(200, "application/json", json);
|
||||
});
|
||||
}
|
||||
|
BIN
data/images/github.ico
Normal file
BIN
data/images/github.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.4 KiB |
@ -13,7 +13,7 @@
|
||||
|
||||
<!-- request CSS from the ESP8266 web server -->
|
||||
<!-- <link rel="stylesheet" href="css/bootstrap.min.css"> -->
|
||||
<!-- <link rel="stylesheet" href="css/jquery.minicolors.min.css"> -->
|
||||
<!-- <link rel="stylesheet" href="css/minicolors.min.css"> -->
|
||||
|
||||
<link rel="stylesheet" href="css/styles.css">
|
||||
|
||||
@ -31,7 +31,7 @@
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a class="navbar-brand" href="https://www.evilgeniuslabs.org" target="_blank"><img src="https://evilgeniuslabs.org/images/atom.svg" style="width: 24px; height: 24px;" /></a>
|
||||
<a class="navbar-brand" href="https://www.evilgeniuslabs.org" target="_blank"><img src="/images/atom196.png" style="width: 24px; height: 24px;" /></a>
|
||||
<a class="navbar-brand" href="https://www.evilgeniuslabs.org" target="_blank">Evil Genius Labs</a>
|
||||
</div>
|
||||
<div class="collapse navbar-collapse" id="navbar-collapse-1">
|
||||
@ -40,11 +40,12 @@
|
||||
<li><a href="/simple.htm" target="_blank" title="Simple Mode">Simple</a></li>
|
||||
<li><a href="/edit.htm" target="_blank" title="Edit Files">Files</a></li>
|
||||
<li><a href="/update" target="_blank" title="Update Firmware">Firmware</a></li>
|
||||
<li><a href="/wifi.htm" target="_blank" title="Wi-Fi Settings">Wi-Fi</a></li>
|
||||
</ul>
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
<li>
|
||||
<a href="https://github.com/jasoncoon/esp8266-fastled-webserver">
|
||||
<img style="height: 16px;" src="https://assets-cdn.github.com/favicon.ico" />
|
||||
<img style="height: 16px;" src="/images/github.ico" />
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
@ -215,7 +216,7 @@
|
||||
</nav>
|
||||
|
||||
<!-- request js from internet CDN -->
|
||||
<script src="https://code.jquery.com/jquery-3.1.1.min.js" integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=" crossorigin="anonymous"></script>
|
||||
<script src="https://code.jquery.com/jquery-3.1.1.min.js" integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=" crossorigin="anonymous"></script> -->
|
||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-minicolors/2.2.4/jquery.minicolors.min.js" integrity="sha256-XAFQ9dZ6hy8p/GRhU8h/8pMvM1etymiJLZW1CiHV3bQ=" crossorigin="anonymous"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/reconnecting-websocket/1.0.0/reconnecting-websocket.min.js" integrity="sha256-A4JwlcDvqO4JXpvEtvWY1RH8JAEMu5W21wP8GUXLUNs=" crossorigin="anonymous"></script>
|
||||
@ -223,7 +224,7 @@
|
||||
<!-- request js from the ESP8266 web server -->
|
||||
<!-- <script src="js/jquery-3.1.1.min.js"></script> -->
|
||||
<!-- <script src="js/bootstrap.min.js"></script> -->
|
||||
<!-- <script src="js/jquery.minicolors.min.js"></script> -->
|
||||
<!-- <script src="js/minicolors.min.js"></script> -->
|
||||
<!-- <script src="js/r-websocket.min.js"></script> -->
|
||||
|
||||
<script src="js/app.js"></script>
|
||||
|
@ -1,3 +1,8 @@
|
||||
// require ./jquery-3.1.1.min.js
|
||||
// require ./bootstrap.min.js
|
||||
// require ./minicolors.min.js
|
||||
// require ./r-websocket.min.js
|
||||
|
||||
// used when hosting the site on the ESP8266
|
||||
var address = location.hostname;
|
||||
var urlBase = "";
|
||||
|
2
data/js/bootstrap.min.js
vendored
2
data/js/bootstrap.min.js
vendored
@ -1,3 +1,5 @@
|
||||
// require ./jquery-3.1.1.min.js
|
||||
|
||||
/*!
|
||||
* Bootstrap v3.3.7 (http://getbootstrap.com)
|
||||
* Copyright 2011-2016 Twitter, Inc.
|
||||
|
@ -1,3 +1,5 @@
|
||||
// require ./jquery-3.1.1.min.js
|
||||
|
||||
/*
|
||||
* jQuery MiniColors: A tiny color picker built on jQuery
|
||||
*
|
95
data/wifi.htm
Normal file
95
data/wifi.htm
Normal file
@ -0,0 +1,95 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>ESP8266 + FastLED by Evil Genius Labs</title>
|
||||
|
||||
<!-- request CSS from internet CDN -->
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
|
||||
|
||||
<!-- request CSS from the ESP8266 web server -->
|
||||
<!-- <link rel="stylesheet" href="css/bootstrap.min.css"> -->
|
||||
|
||||
<link rel="stylesheet" href="css/styles.css">
|
||||
|
||||
<link rel="icon" href="images/atom196.png">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<nav class="navbar navbar-default navbar-static-top" id="top" role="banner">
|
||||
<div class="container">
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar-collapse-1" aria-expanded="false">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a class="navbar-brand" href="https://www.evilgeniuslabs.org" target="_blank"><img src="/images/atom196.png" style="width: 24px; height: 24px;" /></a>
|
||||
<a class="navbar-brand" href="https://www.evilgeniuslabs.org" target="_blank">Evil Genius Labs</a>
|
||||
</div>
|
||||
<div class="collapse navbar-collapse" id="navbar-collapse-1">
|
||||
<ul class="nav navbar-nav">
|
||||
<li><a href="/">ESP8266 + FastLED <span class="sr-only">(current)</span></a></li>
|
||||
<li><a href="/simple.htm" target="_blank" title="Simple Mode">Simple</a></li>
|
||||
<li><a href="/edit.htm" target="_blank" title="Edit Files">Files</a></li>
|
||||
<li><a href="/update" target="_blank" title="Update Firmware">Firmware</a></li>
|
||||
<li class="active"><a href="/wifi.htm" target="_blank" title="Wi-Fi Settings">Wi-Fi</a></li>
|
||||
</ul>
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
<li>
|
||||
<a href="https://github.com/jasoncoon/esp8266-fastled-webserver">
|
||||
<img style="height: 16px;" src="/images/github.ico" />
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div id="container" class="container">
|
||||
|
||||
<form class="form-horizontal" id="form" action="/wifi" method="post">
|
||||
|
||||
<div class="form-group">
|
||||
<label for="inputSSID" class="col-sm-2 control-label">SSID</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" autocorrect="off" autocapitalize="none"
|
||||
class="form-control" id="inputSSID" name="ssid" placeholder="SSID (Wi-Fi network name)">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="inputPassword" class="col-sm-2 control-label">Password</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="password" class="form-control" id="inputPassword" name="password" placeholder="Password">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="col-sm-offset-2 col-sm-10">
|
||||
<button type="submit" class="btn btn-default">Connect</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- request js from internet CDN -->
|
||||
<script src="https://code.jquery.com/jquery-3.1.1.min.js" integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=" crossorigin="anonymous"></script>
|
||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
|
||||
<!-- <script src="https://unpkg.com/isotope-layout@3/dist/isotope.pkgd.min.js"></script> -->
|
||||
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/reconnecting-websocket/1.0.0/reconnecting-websocket.min.js" integrity="sha256-A4JwlcDvqO4JXpvEtvWY1RH8JAEMu5W21wP8GUXLUNs=" crossorigin="anonymous"></script> -->
|
||||
|
||||
<!-- request js from the ESP8266 web server -->
|
||||
<!-- <script src="js/jquery-3.1.1.min.js"></script> -->
|
||||
<!-- <script src="js/bootstrap.min.js"></script> -->
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
@ -16,6 +16,9 @@
|
||||
* 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>
|
||||
FASTLED_USING_NAMESPACE
|
||||
|
||||
@ -24,47 +27,38 @@ extern "C" {
|
||||
}
|
||||
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <ESP8266mDNS.h>
|
||||
//#include <ESP8266mDNS.h>
|
||||
#include <ESP8266WebServer.h>
|
||||
#include <ESP8266HTTPUpdateServer.h>
|
||||
#include <WebSocketsServer.h>
|
||||
#include <FS.h>
|
||||
#include <EEPROM.h>
|
||||
#include <IRremoteESP8266.h>
|
||||
//#include <IRremoteESP8266.h>
|
||||
#include "GradientPalettes.h"
|
||||
|
||||
#define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0]))
|
||||
|
||||
#include "Field.h"
|
||||
|
||||
#define HOSTNAME "ESP8266-" ///< Hostname. The setup function adds the Chip ID at the end.
|
||||
//#define RECV_PIN D4
|
||||
//IRrecv irReceiver(RECV_PIN);
|
||||
|
||||
#define RECV_PIN D4
|
||||
IRrecv irReceiver(RECV_PIN);
|
||||
|
||||
#include "Commands.h"
|
||||
|
||||
const bool apMode = false;
|
||||
|
||||
// AP mode password
|
||||
const char WiFiAPPSK[] = "";
|
||||
|
||||
// Wi-Fi network to connect to (if not in AP mode)
|
||||
const char* ssid = "";
|
||||
const char* password = "";
|
||||
//#include "Commands.h"
|
||||
|
||||
ESP8266WebServer webServer(80);
|
||||
WebSocketsServer webSocketsServer = WebSocketsServer(81);
|
||||
ESP8266HTTPUpdateServer httpUpdateServer;
|
||||
|
||||
#include "WiFi.h"
|
||||
|
||||
#include "FSBrowser.h"
|
||||
|
||||
#define DATA_PIN D8
|
||||
#define LED_TYPE WS2811
|
||||
#define COLOR_ORDER GRB
|
||||
#define NUM_LEDS 24
|
||||
#define DATA_PIN D5
|
||||
#define LED_TYPE WS2812
|
||||
#define COLOR_ORDER RGB
|
||||
#define NUM_LEDS 50
|
||||
|
||||
#define MILLI_AMPS 2000 // IMPORTANT: set the max milli-Amps of your power supply (4A = 4000mA)
|
||||
#define MILLI_AMPS 3000 // IMPORTANT: set the max milli-Amps of your power supply (4A = 4000mA)
|
||||
#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];
|
||||
@ -228,7 +222,7 @@ void setup() {
|
||||
|
||||
FastLED.setBrightness(brightness);
|
||||
|
||||
irReceiver.enableIRIn(); // Start the receiver
|
||||
// irReceiver.enableIRIn(); // Start the receiver
|
||||
|
||||
Serial.println();
|
||||
Serial.print( F("Heap: ") ); Serial.println(system_get_free_heap_size());
|
||||
@ -252,57 +246,7 @@ void setup() {
|
||||
Serial.printf("\n");
|
||||
}
|
||||
|
||||
// Set Hostname.
|
||||
String hostname(HOSTNAME);
|
||||
hostname += String(ESP.getChipId(), HEX);
|
||||
WiFi.hostname(hostname);
|
||||
|
||||
char hostnameChar[hostname.length() + 1];
|
||||
memset(hostnameChar, 0, hostname.length() + 1);
|
||||
|
||||
for (uint8_t i = 0; i < hostname.length(); i++)
|
||||
hostnameChar[i] = hostname.charAt(i);
|
||||
|
||||
MDNS.begin(hostnameChar);
|
||||
|
||||
// Add service to MDNS-SD
|
||||
MDNS.addService("http", "tcp", 80);
|
||||
|
||||
// Print hostname.
|
||||
Serial.println("Hostname: " + hostname);
|
||||
|
||||
if (apMode)
|
||||
{
|
||||
WiFi.mode(WIFI_AP);
|
||||
|
||||
// Do a little work to get a unique-ish name. Append the
|
||||
// last two bytes of the MAC (HEX'd) to "Thing-":
|
||||
uint8_t mac[WL_MAC_ADDR_LENGTH];
|
||||
WiFi.softAPmacAddress(mac);
|
||||
String macID = String(mac[WL_MAC_ADDR_LENGTH - 2], HEX) +
|
||||
String(mac[WL_MAC_ADDR_LENGTH - 1], HEX);
|
||||
macID.toUpperCase();
|
||||
String AP_NameString = "ESP8266-" + macID;
|
||||
|
||||
char AP_NameChar[AP_NameString.length() + 1];
|
||||
memset(AP_NameChar, 0, AP_NameString.length() + 1);
|
||||
|
||||
for (int i = 0; i < AP_NameString.length(); i++)
|
||||
AP_NameChar[i] = AP_NameString.charAt(i);
|
||||
|
||||
WiFi.softAP(AP_NameChar, WiFiAPPSK);
|
||||
|
||||
Serial.printf("Connect to Wi-Fi access point: %s\n", AP_NameChar);
|
||||
Serial.println("and open http://192.168.4.1 in your browser");
|
||||
}
|
||||
else
|
||||
{
|
||||
WiFi.mode(WIFI_STA);
|
||||
Serial.printf("Connecting to %s\n", ssid);
|
||||
if (String(WiFi.SSID()) != String(ssid)) {
|
||||
WiFi.begin(ssid, password);
|
||||
}
|
||||
}
|
||||
initializeWiFi();
|
||||
|
||||
httpUpdateServer.setup(&webServer);
|
||||
|
||||
@ -473,10 +417,11 @@ void loop() {
|
||||
// Add entropy to random number generator; we use a lot of it.
|
||||
random16_add_entropy(random(65535));
|
||||
|
||||
// dnsServer.processNextRequest();
|
||||
webSocketsServer.loop();
|
||||
webServer.handleClient();
|
||||
|
||||
handleIrInput();
|
||||
// handleIrInput();
|
||||
|
||||
if (power == 0) {
|
||||
fill_solid(leds, NUM_LEDS, CRGB::Black);
|
||||
@ -552,212 +497,212 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length
|
||||
}
|
||||
}
|
||||
|
||||
void handleIrInput()
|
||||
{
|
||||
InputCommand command = readCommand();
|
||||
|
||||
if (command != InputCommand::None) {
|
||||
Serial.print("command: ");
|
||||
Serial.println((int) command);
|
||||
}
|
||||
|
||||
switch (command) {
|
||||
case InputCommand::Up: {
|
||||
adjustPattern(true);
|
||||
break;
|
||||
}
|
||||
case InputCommand::Down: {
|
||||
adjustPattern(false);
|
||||
break;
|
||||
}
|
||||
case InputCommand::Power: {
|
||||
setPower(power == 0 ? 1 : 0);
|
||||
break;
|
||||
}
|
||||
case InputCommand::BrightnessUp: {
|
||||
adjustBrightness(true);
|
||||
break;
|
||||
}
|
||||
case InputCommand::BrightnessDown: {
|
||||
adjustBrightness(false);
|
||||
break;
|
||||
}
|
||||
case InputCommand::PlayMode: { // toggle pause/play
|
||||
setAutoplay(!autoplay);
|
||||
break;
|
||||
}
|
||||
|
||||
// pattern buttons
|
||||
|
||||
case InputCommand::Pattern1: {
|
||||
setPattern(0);
|
||||
break;
|
||||
}
|
||||
case InputCommand::Pattern2: {
|
||||
setPattern(1);
|
||||
break;
|
||||
}
|
||||
case InputCommand::Pattern3: {
|
||||
setPattern(2);
|
||||
break;
|
||||
}
|
||||
case InputCommand::Pattern4: {
|
||||
setPattern(3);
|
||||
break;
|
||||
}
|
||||
case InputCommand::Pattern5: {
|
||||
setPattern(4);
|
||||
break;
|
||||
}
|
||||
case InputCommand::Pattern6: {
|
||||
setPattern(5);
|
||||
break;
|
||||
}
|
||||
case InputCommand::Pattern7: {
|
||||
setPattern(6);
|
||||
break;
|
||||
}
|
||||
case InputCommand::Pattern8: {
|
||||
setPattern(7);
|
||||
break;
|
||||
}
|
||||
case InputCommand::Pattern9: {
|
||||
setPattern(8);
|
||||
break;
|
||||
}
|
||||
case InputCommand::Pattern10: {
|
||||
setPattern(9);
|
||||
break;
|
||||
}
|
||||
case InputCommand::Pattern11: {
|
||||
setPattern(10);
|
||||
break;
|
||||
}
|
||||
case InputCommand::Pattern12: {
|
||||
setPattern(11);
|
||||
break;
|
||||
}
|
||||
|
||||
// custom color adjustment buttons
|
||||
|
||||
case InputCommand::RedUp: {
|
||||
solidColor.red += 8;
|
||||
setSolidColor(solidColor);
|
||||
break;
|
||||
}
|
||||
case InputCommand::RedDown: {
|
||||
solidColor.red -= 8;
|
||||
setSolidColor(solidColor);
|
||||
break;
|
||||
}
|
||||
case InputCommand::GreenUp: {
|
||||
solidColor.green += 8;
|
||||
setSolidColor(solidColor);
|
||||
break;
|
||||
}
|
||||
case InputCommand::GreenDown: {
|
||||
solidColor.green -= 8;
|
||||
setSolidColor(solidColor);
|
||||
break;
|
||||
}
|
||||
case InputCommand::BlueUp: {
|
||||
solidColor.blue += 8;
|
||||
setSolidColor(solidColor);
|
||||
break;
|
||||
}
|
||||
case InputCommand::BlueDown: {
|
||||
solidColor.blue -= 8;
|
||||
setSolidColor(solidColor);
|
||||
break;
|
||||
}
|
||||
|
||||
// color buttons
|
||||
|
||||
case InputCommand::Red: {
|
||||
setSolidColor(CRGB::Red);
|
||||
break;
|
||||
}
|
||||
case InputCommand::RedOrange: {
|
||||
setSolidColor(CRGB::OrangeRed);
|
||||
break;
|
||||
}
|
||||
case InputCommand::Orange: {
|
||||
setSolidColor(CRGB::Orange);
|
||||
break;
|
||||
}
|
||||
case InputCommand::YellowOrange: {
|
||||
setSolidColor(CRGB::Goldenrod);
|
||||
break;
|
||||
}
|
||||
case InputCommand::Yellow: {
|
||||
setSolidColor(CRGB::Yellow);
|
||||
break;
|
||||
}
|
||||
|
||||
case InputCommand::Green: {
|
||||
setSolidColor(CRGB::Green);
|
||||
break;
|
||||
}
|
||||
case InputCommand::Lime: {
|
||||
setSolidColor(CRGB::Lime);
|
||||
break;
|
||||
}
|
||||
case InputCommand::Aqua: {
|
||||
setSolidColor(CRGB::Aqua);
|
||||
break;
|
||||
}
|
||||
case InputCommand::Teal: {
|
||||
setSolidColor(CRGB::Teal);
|
||||
break;
|
||||
}
|
||||
case InputCommand::Navy: {
|
||||
setSolidColor(CRGB::Navy);
|
||||
break;
|
||||
}
|
||||
|
||||
case InputCommand::Blue: {
|
||||
setSolidColor(CRGB::Blue);
|
||||
break;
|
||||
}
|
||||
case InputCommand::RoyalBlue: {
|
||||
setSolidColor(CRGB::RoyalBlue);
|
||||
break;
|
||||
}
|
||||
case InputCommand::Purple: {
|
||||
setSolidColor(CRGB::Purple);
|
||||
break;
|
||||
}
|
||||
case InputCommand::Indigo: {
|
||||
setSolidColor(CRGB::Indigo);
|
||||
break;
|
||||
}
|
||||
case InputCommand::Magenta: {
|
||||
setSolidColor(CRGB::Magenta);
|
||||
break;
|
||||
}
|
||||
|
||||
case InputCommand::White: {
|
||||
setSolidColor(CRGB::White);
|
||||
break;
|
||||
}
|
||||
case InputCommand::Pink: {
|
||||
setSolidColor(CRGB::Pink);
|
||||
break;
|
||||
}
|
||||
case InputCommand::LightPink: {
|
||||
setSolidColor(CRGB::LightPink);
|
||||
break;
|
||||
}
|
||||
case InputCommand::BabyBlue: {
|
||||
setSolidColor(CRGB::CornflowerBlue);
|
||||
break;
|
||||
}
|
||||
case InputCommand::LightBlue: {
|
||||
setSolidColor(CRGB::LightBlue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
//void handleIrInput()
|
||||
//{
|
||||
// InputCommand command = readCommand();
|
||||
//
|
||||
// if (command != InputCommand::None) {
|
||||
// Serial.print("command: ");
|
||||
// Serial.println((int) command);
|
||||
// }
|
||||
//
|
||||
// switch (command) {
|
||||
// case InputCommand::Up: {
|
||||
// adjustPattern(true);
|
||||
// break;
|
||||
// }
|
||||
// case InputCommand::Down: {
|
||||
// adjustPattern(false);
|
||||
// break;
|
||||
// }
|
||||
// case InputCommand::Power: {
|
||||
// setPower(power == 0 ? 1 : 0);
|
||||
// break;
|
||||
// }
|
||||
// case InputCommand::BrightnessUp: {
|
||||
// adjustBrightness(true);
|
||||
// break;
|
||||
// }
|
||||
// case InputCommand::BrightnessDown: {
|
||||
// adjustBrightness(false);
|
||||
// break;
|
||||
// }
|
||||
// case InputCommand::PlayMode: { // toggle pause/play
|
||||
// setAutoplay(!autoplay);
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
// // pattern buttons
|
||||
//
|
||||
// case InputCommand::Pattern1: {
|
||||
// setPattern(0);
|
||||
// break;
|
||||
// }
|
||||
// case InputCommand::Pattern2: {
|
||||
// setPattern(1);
|
||||
// break;
|
||||
// }
|
||||
// case InputCommand::Pattern3: {
|
||||
// setPattern(2);
|
||||
// break;
|
||||
// }
|
||||
// case InputCommand::Pattern4: {
|
||||
// setPattern(3);
|
||||
// break;
|
||||
// }
|
||||
// case InputCommand::Pattern5: {
|
||||
// setPattern(4);
|
||||
// break;
|
||||
// }
|
||||
// case InputCommand::Pattern6: {
|
||||
// setPattern(5);
|
||||
// break;
|
||||
// }
|
||||
// case InputCommand::Pattern7: {
|
||||
// setPattern(6);
|
||||
// break;
|
||||
// }
|
||||
// case InputCommand::Pattern8: {
|
||||
// setPattern(7);
|
||||
// break;
|
||||
// }
|
||||
// case InputCommand::Pattern9: {
|
||||
// setPattern(8);
|
||||
// break;
|
||||
// }
|
||||
// case InputCommand::Pattern10: {
|
||||
// setPattern(9);
|
||||
// break;
|
||||
// }
|
||||
// case InputCommand::Pattern11: {
|
||||
// setPattern(10);
|
||||
// break;
|
||||
// }
|
||||
// case InputCommand::Pattern12: {
|
||||
// setPattern(11);
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
// // custom color adjustment buttons
|
||||
//
|
||||
// case InputCommand::RedUp: {
|
||||
// solidColor.red += 8;
|
||||
// setSolidColor(solidColor);
|
||||
// break;
|
||||
// }
|
||||
// case InputCommand::RedDown: {
|
||||
// solidColor.red -= 8;
|
||||
// setSolidColor(solidColor);
|
||||
// break;
|
||||
// }
|
||||
// case InputCommand::GreenUp: {
|
||||
// solidColor.green += 8;
|
||||
// setSolidColor(solidColor);
|
||||
// break;
|
||||
// }
|
||||
// case InputCommand::GreenDown: {
|
||||
// solidColor.green -= 8;
|
||||
// setSolidColor(solidColor);
|
||||
// break;
|
||||
// }
|
||||
// case InputCommand::BlueUp: {
|
||||
// solidColor.blue += 8;
|
||||
// setSolidColor(solidColor);
|
||||
// break;
|
||||
// }
|
||||
// case InputCommand::BlueDown: {
|
||||
// solidColor.blue -= 8;
|
||||
// setSolidColor(solidColor);
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
// // color buttons
|
||||
//
|
||||
// case InputCommand::Red: {
|
||||
// setSolidColor(CRGB::Red);
|
||||
// break;
|
||||
// }
|
||||
// case InputCommand::RedOrange: {
|
||||
// setSolidColor(CRGB::OrangeRed);
|
||||
// break;
|
||||
// }
|
||||
// case InputCommand::Orange: {
|
||||
// setSolidColor(CRGB::Orange);
|
||||
// break;
|
||||
// }
|
||||
// case InputCommand::YellowOrange: {
|
||||
// setSolidColor(CRGB::Goldenrod);
|
||||
// break;
|
||||
// }
|
||||
// case InputCommand::Yellow: {
|
||||
// setSolidColor(CRGB::Yellow);
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
// case InputCommand::Green: {
|
||||
// setSolidColor(CRGB::Green);
|
||||
// break;
|
||||
// }
|
||||
// case InputCommand::Lime: {
|
||||
// setSolidColor(CRGB::Lime);
|
||||
// break;
|
||||
// }
|
||||
// case InputCommand::Aqua: {
|
||||
// setSolidColor(CRGB::Aqua);
|
||||
// break;
|
||||
// }
|
||||
// case InputCommand::Teal: {
|
||||
// setSolidColor(CRGB::Teal);
|
||||
// break;
|
||||
// }
|
||||
// case InputCommand::Navy: {
|
||||
// setSolidColor(CRGB::Navy);
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
// case InputCommand::Blue: {
|
||||
// setSolidColor(CRGB::Blue);
|
||||
// break;
|
||||
// }
|
||||
// case InputCommand::RoyalBlue: {
|
||||
// setSolidColor(CRGB::RoyalBlue);
|
||||
// break;
|
||||
// }
|
||||
// case InputCommand::Purple: {
|
||||
// setSolidColor(CRGB::Purple);
|
||||
// break;
|
||||
// }
|
||||
// case InputCommand::Indigo: {
|
||||
// setSolidColor(CRGB::Indigo);
|
||||
// break;
|
||||
// }
|
||||
// case InputCommand::Magenta: {
|
||||
// setSolidColor(CRGB::Magenta);
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
// case InputCommand::White: {
|
||||
// setSolidColor(CRGB::White);
|
||||
// break;
|
||||
// }
|
||||
// case InputCommand::Pink: {
|
||||
// setSolidColor(CRGB::Pink);
|
||||
// break;
|
||||
// }
|
||||
// case InputCommand::LightPink: {
|
||||
// setSolidColor(CRGB::LightPink);
|
||||
// break;
|
||||
// }
|
||||
// case InputCommand::BabyBlue: {
|
||||
// setSolidColor(CRGB::CornflowerBlue);
|
||||
// break;
|
||||
// }
|
||||
// case InputCommand::LightBlue: {
|
||||
// setSolidColor(CRGB::LightBlue);
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
void loadSettings()
|
||||
{
|
||||
@ -1001,7 +946,7 @@ void sinelon()
|
||||
{
|
||||
// a colored dot sweeping back and forth, with fading trails
|
||||
fadeToBlackBy( leds, NUM_LEDS, 20);
|
||||
int pos = beatsin16(speed, 0, NUM_LEDS);
|
||||
int pos = beatsin16(speed, 0, NUM_LEDS - 1);
|
||||
static int prevpos = 0;
|
||||
CRGB color = ColorFromPalette(palettes[currentPaletteIndex], gHue, 255);
|
||||
if( pos < prevpos ) {
|
||||
|
Reference in New Issue
Block a user