diff --git a/HyperionRGB/.gitignore b/HyperionRGB/.gitignore index 0001b6f..a0a46f9 100644 --- a/HyperionRGB/.gitignore +++ b/HyperionRGB/.gitignore @@ -1 +1,2 @@ -ConfigStatic.h \ No newline at end of file +ConfigStatic.h +ConfigStatic.h-* \ No newline at end of file diff --git a/HyperionRGB/EnhancedThread.cpp b/HyperionRGB/EnhancedThread.cpp index 1f87208..d7b08de 100644 --- a/HyperionRGB/EnhancedThread.cpp +++ b/HyperionRGB/EnhancedThread.cpp @@ -1,25 +1,6 @@ -#include "EnhancedThread.h" - -void EnhancedThread::run() { - Thread::run(); - if (_runOnce) - Thread::enabled = false; -} - -void EnhancedThread::runIfNeeded(void) { - if(Thread::shouldRun()) - Thread::run(); -} - -void EnhancedThread::reset(void) { - Thread::enabled = true; - Thread::runned(); -} - -void EnhancedThread::setRunOnce(bool runOnce) { - _runOnce = runOnce; -} -unsigned long EnhancedThread::getInterval(void) { - return interval; -} - +//#include "EnhancedThread.h" +/* + * Put everything into the EnhancedThread.h to make it compatible with the ESP32 + * There seems to be a bug in the ArduinoThread lib + * + */ diff --git a/HyperionRGB/EnhancedThread.h b/HyperionRGB/EnhancedThread.h index 1a53491..6bd20d5 100644 --- a/HyperionRGB/EnhancedThread.h +++ b/HyperionRGB/EnhancedThread.h @@ -4,7 +4,7 @@ #include "BaseHeader.h" #include -class EnhancedThread: public Thread { +class EnhancedThread : public Thread { public: void run(void), @@ -16,4 +16,27 @@ class EnhancedThread: public Thread { bool _runOnce; }; +void EnhancedThread::run() { + Thread::run(); + if (_runOnce) + Thread::enabled = false; +} + +void EnhancedThread::runIfNeeded(void) { + if(Thread::shouldRun()) + Thread::run(); +} + +void EnhancedThread::reset(void) { + Thread::enabled = true; + Thread::runned(); +} + +void EnhancedThread::setRunOnce(bool runOnce) { + _runOnce = runOnce; +} +unsigned long EnhancedThread::getInterval(void) { + return interval; +} + #endif diff --git a/HyperionRGB/HyperionRGB.ino b/HyperionRGB/HyperionRGB.ino index 6f5d9e9..868230a 100644 --- a/HyperionRGB/HyperionRGB.ino +++ b/HyperionRGB/HyperionRGB.ino @@ -15,7 +15,7 @@ #include "WrapperWebconfig.h" -#define LED D0 // LED in NodeMCU at pin GPIO16 (D0). +#define LED LED_BUILTIN // LED in NodeMCU at pin GPIO16 (D0) or LED_BUILTIN @Lolin32. int ledState = LOW; LoggerInit loggerInit; diff --git a/HyperionRGB/WrapperJsonServer.cpp b/HyperionRGB/WrapperJsonServer.cpp index bec2a47..a22453c 100644 --- a/HyperionRGB/WrapperJsonServer.cpp +++ b/HyperionRGB/WrapperJsonServer.cpp @@ -7,6 +7,7 @@ WrapperJsonServer::WrapperJsonServer(uint16_t ledCount, uint16_t tcpPort) : _tcpServer(tcpPort) { _ledCount = ledCount; _tcpPort = tcpPort; + _activeLedColor = new byte[3]; } void WrapperJsonServer::begin(void) { @@ -48,14 +49,31 @@ void WrapperJsonServer::readData(void) { String command = root["command"].asString(); if (command.equals("serverinfo")) { Log.info("serverinfo"); - _tcpClient.println("{\"info\":{\"effects\":[" + _tcpClient.print("{\"info\":{\"effects\":[" "{\"args\":{\"speed\":1.0},\"name\":\"Hyperion UDP\",\"script\":\"hyperion_udp\"}," "{\"args\":{\"speed\":2.0},\"name\":\"Rainbow mood\",\"script\":\"rainbow\"}," "{\"args\":{\"speed\":62.5},\"name\":\"Fire2012\",\"script\":\"fire2012\"}" "]," - "\"hostname\":\"ESP8266\"," - "\"priorities\":[],\"transform\":[{\"blacklevel\":[0.0,0.0,0.0],\"gamma\":[1.0,1.0,1.0],\"id\":\"default\",\"saturationGain\":1.0,\"threshold\":[0.0,0.0,0.0],\"valueGain\":1.0,\"whitelevel\":[1.0,1.0,1.0]}]}," - "\"success\":true}"); + "\"activeLedColor\":[{\"RGB Value\":["); + //Dirty hack, workaround for each leds state of newer hyperion versions + /* "activeLedColor" : [ + { + "HEX Value" : [ "0xFF0036" ], + "HSL Value" : [ 347, 1.0, 0.50 ], + "RGB Value" : [ 255, 0, 54 ] + } + ], */ + _tcpClient.print(_activeLedColor[0]); + _tcpClient.print(","); + _tcpClient.print(_activeLedColor[1]); + _tcpClient.print(","); + _tcpClient.print(_activeLedColor[2]); + + _tcpClient.print("]}]," + "\"hostname\":\"ESP8266\"," + "\"priorities\":[],\"transform\":[{\"blacklevel\":[0.0,0.0,0.0],\"gamma\":[1.0,1.0,1.0],\"id\":\"default\",\"saturationGain\":1.0,\"threshold\":[0.0,0.0,0.0],\"valueGain\":1.0,\"whitelevel\":[1.0,1.0,1.0]}]}," + "\"success\":true}"); + _tcpClient.println(""); } else if (command.equals("color")) { int duration = root["duration"]; ledColorWipe(root["color"][0], root["color"][1], root["color"][2]); @@ -91,6 +109,9 @@ void WrapperJsonServer::onLedColorWipe(void(* function) (byte, byte, byte)) { ledColorWipePointer = function; } void WrapperJsonServer::ledColorWipe(byte r, byte g, byte b) { + _activeLedColor[0] = r; + _activeLedColor[1] = g; + _activeLedColor[2] = b; if (ledColorWipePointer) { ledColorWipePointer(r, g, b); } @@ -100,6 +121,9 @@ void WrapperJsonServer::onClearCmd(void(* function) (void)) { clearCmdPointer = function; } void WrapperJsonServer::clearCmd(void) { + _activeLedColor[0] = 0; + _activeLedColor[1] = 0; + _activeLedColor[2] = 0; if (clearCmdPointer) { clearCmdPointer(); } diff --git a/HyperionRGB/WrapperJsonServer.h b/HyperionRGB/WrapperJsonServer.h index 62c808d..e9d401b 100644 --- a/HyperionRGB/WrapperJsonServer.h +++ b/HyperionRGB/WrapperJsonServer.h @@ -41,6 +41,8 @@ class WrapperJsonServer { uint16_t _ledCount; uint16_t _tcpPort; + + byte* _activeLedColor; }; #endif diff --git a/HyperionRGB/WrapperWebconfig.cpp b/HyperionRGB/WrapperWebconfig.cpp index 8d5635e..85bbcf2 100644 --- a/HyperionRGB/WrapperWebconfig.cpp +++ b/HyperionRGB/WrapperWebconfig.cpp @@ -1,35 +1,35 @@ #include "WrapperWebconfig.h" void WrapperWebconfig::begin() { - _server.onNotFound([&](){ WrapperWebconfig::handleNotFound(); }); - _server.on("/", [&](){ WrapperWebconfig::handleRoot(); }); - _server.begin(); + _server->onNotFound([&](){ WrapperWebconfig::handleNotFound(); }); + _server->on("/", [&](){ WrapperWebconfig::handleRoot(); }); + _server->begin(); } void WrapperWebconfig::handle(void) { - _server.handleClient(); + _server->handleClient(); } void WrapperWebconfig::handleNotFound(void) { String message = "File Not Found\n\n"; message += "URI: "; - message += _server.uri(); + message += _server->uri(); message += "\nMethod: "; - message += (_server.method() == HTTP_GET)?"GET":"POST"; + message += (_server->method() == HTTP_GET)?"GET":"POST"; message += "\nArguments: "; - message += _server.args(); + message += _server->args(); message += "\n"; - for (uint8_t i=0; i<_server.args(); i++){ - message += " " + _server.argName(i) + ": " + _server.arg(i) + "\n"; + for (uint8_t i=0; i<_server->args(); i++){ + message += " " + _server->argName(i) + ": " + _server->arg(i) + "\n"; } - _server.send(404, "text/plain", message); + _server->send(404, "text/plain", message); } void WrapperWebconfig::handleRoot(void) { Log.debug("Webconfig started HEAP=%i", ESP.getFreeHeap()); initHelperVars(); Log.debug("Webconfig initialized HEAP=%i", ESP.getFreeHeap()); - if (_server.method() == HTTP_POST) { + if (_server->method() == HTTP_POST) { Log.debug("POST HEAP=%i", ESP.getFreeHeap()); changeConfig(); } @@ -38,7 +38,7 @@ void WrapperWebconfig::handleRoot(void) { Log.debug("Webconfig max HEAP=%i", ESP.getFreeHeap()); //Log.debug("Webconfig cleared HEAP=%i", ESP.getFreeHeap()); - _server.send(200, "text/html", message); + _server->send(200, "text/html", message); Log.debug("Webconfig sent HEAP=%i", ESP.getFreeHeap()); } @@ -76,9 +76,9 @@ void WrapperWebconfig::changeConfig(void) { boolean restart = false; boolean loadStatic = false; - for (uint8_t i=0; i<_server.args(); i++){ - String argName = _server.argName(i); - String argValue = _server.arg(i); + for (uint8_t i=0; i<_server->args(); i++){ + String argName = _server->argName(i); + String argValue = _server->arg(i); Log.debug("Config: \"%s\":\"%s\"", argName.c_str(), argValue.c_str()); diff --git a/HyperionRGB/WrapperWebconfig.h b/HyperionRGB/WrapperWebconfig.h index 0241e47..0664882 100644 --- a/HyperionRGB/WrapperWebconfig.h +++ b/HyperionRGB/WrapperWebconfig.h @@ -2,7 +2,11 @@ #define WrapperWebconfig_h #include "BaseHeader.h" -#include +#if defined(ESP8266) + #include +#elif defined(ESP32) + #include +#endif #include class SelectEntryBase { @@ -74,9 +78,13 @@ class WrapperWebconfig { template T getSelectedEntry(String selectedEntryValue, LinkedList* target); - LinkedList* _idleModes;; - - ESP8266WebServer _server = ESP8266WebServer(80); + LinkedList* _idleModes; + + #if defined(ESP8266) + ESP8266WebServer* _server = new ESP8266WebServer(80); + #elif defined(ESP32) + ESP32WebServer* _server = new ESP32WebServer(80); + #endif }; #endif diff --git a/HyperionRGB/WrapperWiFi.h b/HyperionRGB/WrapperWiFi.h index d20e07f..5bb3072 100644 --- a/HyperionRGB/WrapperWiFi.h +++ b/HyperionRGB/WrapperWiFi.h @@ -2,8 +2,14 @@ #define WrapperWiFi_h #include "BaseHeader.h" -#include -#include + +#if defined(ESP8266) + #include + #include +#elif defined(ESP32) + #include + #include +#endif class WrapperWiFi { public: diff --git a/README.md b/README.md index 2b7527b..9638e44 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,10 @@ -# ESP8266 Hyperion LED Controller +# Hyperion LED Controller for ESP8266/ESP32 +<<<<<<< HEAD This code allows you to use a ESP8266 with a fitting led strip as extension for [hyperion](https://github.com/hyperion-project) (ambilight clone). +======= +This code allows you to use a ESP8266/ESP32 with a fitting led strip as extension for [hyperion](https://github.com/hyperion-project) (ambilight clone). +>>>>>>> develop You need to configure hyperion to stream the leds as UDP to the esp. German Tutorial: @@ -8,6 +12,7 @@ https://forum-raspberrypi.de/forum/thread/25242-tutorial-esp8266-nodemcu-addon-w Tested with following following libraries (other versions may work): # IDE +<<<<<<< HEAD a) Arduino IDE 1.6.12, 1.8.5 # Board Library @@ -32,6 +37,23 @@ e) Logging https://github.com/SciLor/Arduino-logging-library - install manually: - You maydefine Wifi configuration but you can also change it from the Webinterface 3. Open the `HyperionRGB.ino` the Arduino IDE 4. Compile and upload to your board +======= +a) Arduino IDE 1.8.5 + +# Board Library +a) esp8266 2.4.1 + +b) for esp32 https://github.com/espressif/arduino-esp32 + +http://arduino.esp8266.com/stable/package_esp8266com_index.json + +add to board urls - Version 2.4.0 don't work (bug see https://github.com/esp8266/Arduino/issues/4085) + +# Libraries +a) ArduinoThread 2.1.1 + +b) ArduinoJSON 5.12.0 +>>>>>>> develop # Configuration of Hyperion You need two running hyperion instances. The first grabs the data on e.g. a rasbperry pi and controls any local attached LED strips. This first instance is configured to forward its data to a second hyperion instance on the same machine. Be sure to only forward the UDP data: @@ -67,5 +89,60 @@ The second hyperion instance is configured to use UDP as device so that it can t }, ``` +<<<<<<< HEAD +======= +d) FastLED 3.1.6 + +e) Logging https://github.com/SciLor/Arduino-logging-library - install manually: Download zip from github and install via Arduino IDE, Sketch -> Include Library -> Add .ZIP Library + +f) ESP32 Webserver https://github.com/nhatuan84/esp32-webserver - install manually (for esp32 only) + +# Installation + +# Configuration of the board +1. Go to the `HyperionRGB` folder and create a copy of `ConfigStatic.h.example`. Remove the `.example` suffix +2. Configure the `ConfigStatic.h` for your needs: + - Select your LED chip type. All LEDs of the [FastLed](https://github.com/FastLED/FastLED) libraries are supported + - Configure the used LED pins. You can also change the Pin Order. The NodeMCU order doesn't work sometimes to please also try the `RAW_PIN_ORDER`` + - Define the number of used LEDs + - Define one of the standard modes which are active when your light is idle. Choose one from: OFF, HYPERION_UDP, STATIC_COLOR, RAINBOW, FIRE2012 + - You maydefine Wifi configuration but you can also change it from the Webinterface +3. Open the `HyperionRGB.ino` the Arduino IDE +4. Compile and upload to your board + +# Configuration of Hyperion +You need two running hyperion instances. The first grabs the data on e.g. a rasbperry pi and controls any local attached LED strips. This first instance is configured to forward its data to a second hyperion instance on the same machine. Be sure to only forward the UDP data: + +``` +"forwarder" : +{ +"proto" : [ "localhost:19447" ] +}, +``` + +The second hyperion instance is configured to use UDP as device so that it can talk to the ESP directly. This second hyperion instance can run on the same machine as the first instance. Just make sure that you set the UDP ports, hostnames/IPs and LED number accordingly to the values you've configured for the ESP. + +``` +{ + "colorOrder" : "rgb", + "maxpacket" : 1450, + "name" : "AmbiSZ-ESP8266", + "output" : "ESP8266:19446", /// + "protocol" : 0, + "rate" : 250000, + "type" : "udp" +}, + + +"protoServer" : +{ +"port" : 19447 +}, +"jsonServer" : +{ +"port" : 19446 +}, +``` +>>>>>>> develop There's a detailed instruction page for [controlling multiple devices](https://hyperion-project.org/wiki/Controlling-Multiple-Devices). \ No newline at end of file