Skip to content

Commit

Permalink
Most 0.6.0 features working
Browse files Browse the repository at this point in the history
LEDs now turn on instantly after boot
Support Hardware ESP32 RMT NeopixelBus library
Added setting to force old LED boot behavior (init after WiFi)
Fixed overlay switching bug
Fixed ? characters in usused macros
Added transitionDelay to notifier packet
  • Loading branch information
Aircoookie committed Mar 15, 2018
1 parent 8d7a066 commit 89afdd2
Show file tree
Hide file tree
Showing 14 changed files with 96 additions and 56 deletions.
9 changes: 6 additions & 3 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,25 @@
WLED is a fast and (relatively) secure implementation of an ESP8266 webserver to control NeoPixel (WS2812B) LEDs!
Now also with experimental ESP32 support.

### Features: (V0.5.0)
### Features: (V0.6.0)
- RGB, HSB, and brightness sliders
- Settings page - configuration over network
- Access Point and station mode - automatic failsafe AP
- WS2812FX library integrated for over 50 special effects!
- Secondary color support lets you use even more effect combinations
- Alexa smart home device server (including dimming)
- Beta syncronization to Philips hue lights
- Support for RGBW strips
- 25 user presets! Save your favorite colors and effects and apply them easily!
- HTTP request API for simple integration
- Macro functions to automatically execute API calls
- Nightlight function (gradually dims down)
- Notifier function (multiple ESPs sync color via UDP broadcast)
- Support for power pushbutton
- Custom Theater Chase
- Full OTA software update capability (HTTP and ArduinoOTA)
- Password protected OTA page for added security (OTA lock)
- Alexa smart home device server (including dimming)
- NTP and experimental analog clock function
- NTP and configurable analog clock function
- Support for the Cronixie Clock kit by Diamex
- Realtime UDP Packet Control (WARLS) possible
- Client HTML UI controlled, customizable themes
Expand Down
9 changes: 7 additions & 2 deletions wled00/WS2812FX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2040,12 +2040,17 @@ void WS2812FX::setBrightness(byte b)
void WS2812FX::show()
{
#ifdef ARDUINO_ARCH_ESP32
#ifdef WORKAROUND_ESP32_BITBANG
delay(1);
portDISABLE_INTERRUPTS(); //this is a workaround to prevent flickering (see https://github.com/adafruit/Adafruit_NeoPixel/issues/139)
#endif
#endif
NeoPixelBrightnessBus::Show();

#ifdef ARDUINO_ARCH_ESP32
#ifdef WORKAROUND_ESP32_BITBANG
portENABLE_INTERRUPTS();
#else
NeoPixelBrightnessBus::Show();
#endif
#endif
}

Expand Down
6 changes: 6 additions & 0 deletions wled00/WS2812FX.h
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
//#define RGBW
#define PIN 2 //strip pin. Only change for ESP32
#define WORKAROUND_ESP32_BITBANG
//see https://github.com/Aircoookie/WLED/issues/2 for flicker free ESP32 support

//automatically uses the right driver method for each platform
#ifdef ARDUINO_ARCH_ESP32
#ifdef WORKAROUND_ESP32_BITBANG
#define PIXELMETHOD NeoEsp32BitBangWs2813Method
#else
#define PIXELMETHOD NeoEsp32RmtWS2813_V3Method
#endif
#else
#define PIXELMETHOD NeoEsp8266Uart800KbpsMethod
#endif

Expand Down
Binary file modified wled00/data/settings_leds.htm
Binary file not shown.
1 change: 1 addition & 0 deletions wled00/htmls01.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ Default Target brightness: <input name="TB" type="number" min="0" max="255" requ
Fade down: <input type="checkbox" name="TW"><br>
<h3>Advanced</h3>
Reverse LED order (rotate 180): <input type="checkbox" name="RV"><br>
Init LEDs after WiFi: <input type="checkbox" name="EI"><br>
WARLS offset: <input name="WO" type="number" min="-255" max="255" required><hr>
<button type="button" onclick="B()">Back</button><button type="submit">Save</button>
</form>
Expand Down
33 changes: 18 additions & 15 deletions wled00/wled00.ino
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
#include "WS2812FX.h"

//version in format yymmddb (b = daily build)
#define VERSION 1803144
#define VERSION 1803146
const String versionString = "0.6.0";

//AP and OTA default passwords (change them!)
Expand Down Expand Up @@ -74,6 +74,7 @@ IPAddress staticSubnet(255, 255, 255, 0);
IPAddress staticDNS(8, 8, 8, 8); //only for NTP
bool useHSB = false, useHSBDefault = false;
bool turnOnAtBoot = true;
bool initLedsLast = false;
byte bootPreset = 0;
byte colS[]{255, 159, 0};
byte colSecS[]{0, 0, 0};
Expand All @@ -99,8 +100,7 @@ byte effectSpeedDefault = 75;
byte effectIntensityDefault = 128;
//NTP stuff
bool ntpEnabled = false;
IPAddress ntpServerIP;
const char* ntpServerName = "0.wled.pool.ntp.org";
String ntpServerName = "0.wled.pool.ntp.org";
//custom chase
byte ccNumPrimary = 2;
byte ccNumSecondary = 4;
Expand All @@ -123,20 +123,13 @@ unsigned long countdownTime = 1514764800L;
double transitionResolution = 0.011;

//hue
long hueLastRequestSent = 0;
bool huePollingEnabled = false, hueAttempt = false;
uint16_t huePollIntervalMs = 2500;
uint32_t huePollIntervalMsTemp = 2500;
String hueApiKey = "api";
byte huePollLightId = 1;
IPAddress hueIP = (0,0,0,0);
bool notifyHue = true;
bool hueApplyOnOff = true, hueApplyBri = true, hueApplyColor = true;
String hueError = "Inactive";
uint16_t hueFailCount = 0;
float hueXLast=0, hueYLast=0;
uint16_t hueHueLast=0, hueCtLast=0;
byte hueSatLast=0, hueBriLast=0;

//Internal vars
byte col[]{0, 0, 0};
Expand Down Expand Up @@ -176,15 +169,19 @@ String cssFont="Verdana";
String cssColorString="";
//NTP stuff
bool ntpConnected = false;
unsigned int ntpLocalPort = 2390;
const uint16_t NTP_PACKET_SIZE = 48;
byte ntpPacketBuffer[NTP_PACKET_SIZE];
unsigned long ntpLastSyncTime = 999000000L;
unsigned long ntpPacketSentTime = 999000000L;
byte currentTimezone = 0;
time_t local;
int utcOffsetSecs = 0;

//hue
String hueError = "Inactive";
uint16_t hueFailCount = 0;
float hueXLast=0, hueYLast=0;
uint16_t hueHueLast=0, hueCtLast=0;
byte hueSatLast=0, hueBriLast=0;
long hueLastRequestSent = 0;
uint32_t huePollIntervalMsTemp = huePollIntervalMs;

//overlay stuff
byte overlayDefault = 0;
byte overlayCurrent = 0;
Expand Down Expand Up @@ -242,6 +239,12 @@ HTTPClient hueClient;
ESP8266HTTPUpdateServer httpUpdater;
WiFiUDP notifierUdp;
WiFiUDP ntpUdp;
IPAddress ntpServerIP;
unsigned int ntpLocalPort = 2390;
const uint16_t NTP_PACKET_SIZE = 48;
byte ntpPacketBuffer[NTP_PACKET_SIZE];
unsigned long ntpLastSyncTime = 999000000L;
unsigned long ntpPacketSentTime = 999000000L;

WS2812FX strip = WS2812FX(LEDCOUNT);

Expand Down
10 changes: 8 additions & 2 deletions wled00/wled01_eeprom.ino
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@
#define EEPSIZE 3072

//eeprom Version code, enables default settings instead of 0 init on update
#define EEPVER 5
#define EEPVER 6
//0 -> old version, default
//1 -> 0.4p 1711272 and up
//2 -> 0.4p 1711302 and up
//3 -> 0.4 1712121 and up
//4 -> 0.5.0 and up
//5 -> 0.6.0 and up
//5 -> 0.5.1 and up
//6 -> 0.6.0 and up

//todo add settings
void clearEEPROM()
Expand Down Expand Up @@ -145,6 +146,7 @@ void saveSettingsToEEPROM()
EEPROM.write(394, (abs(utcOffsetSecs) >> 0) & 0xFF);
EEPROM.write(395, (abs(utcOffsetSecs) >> 8) & 0xFF);
EEPROM.write(396, (utcOffsetSecs<0)); //is negative
EEPROM.write(397, initLedsLast);

for (int k=0;k<6;k++){
int in = 900+k*8;
Expand Down Expand Up @@ -380,6 +382,8 @@ void loadSettingsFromEEPROM(bool first)
hueApplyBri = EEPROM.read(2104);
hueApplyColor = EEPROM.read(2105);
huePollLightId = EEPROM.read(2106);
}
if (lastEEPROMversion > 5) {
overlayMin = EEPROM.read(2150);
overlayMax = EEPROM.read(2151);
analogClock12pixel = EEPROM.read(2152);
Expand Down Expand Up @@ -415,6 +419,7 @@ void loadSettingsFromEEPROM(bool first)
wifiLock = EEPROM.read(393);
utcOffsetSecs = ((EEPROM.read(394) << 0) & 0xFF) + ((EEPROM.read(395) << 8) & 0xFF00);
if (EEPROM.read(396)) utcOffsetSecs = -utcOffsetSecs; //negative
initLedsLast = EEPROM.read(397);

//favorite setting memory (25 slots/ each 20byte)
//400 - 899 reserved
Expand Down Expand Up @@ -519,6 +524,7 @@ String loadMacro(byte index)
if (EEPROM.read(i) == 0) break;
m += char(EEPROM.read(i));
}
if (m.charAt(0) < 65 || m.charAt(0) > 90) return ""; //do simple check if macro is valid (capital first letter)
return m;
}

Expand Down
1 change: 1 addition & 0 deletions wled00/wled02_xml.ino
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ String getSettings(byte subPage)
resp += ds + "TL" + v + nightlightDelayMins +";";
resp += ds + "TW" + c + nightlightFade +";";
resp += ds + "RV" + c + reverseMode +";";
resp += ds + "EI" + c + initLedsLast +";";
resp += ds + "WO" + v + arlsOffset +";";
}

Expand Down
1 change: 1 addition & 0 deletions wled00/wled03_set.ino
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ void handleSettingsSet(byte subPage)
}
nightlightFade = server.hasArg("TW");
reverseMode = server.hasArg("RV");
initLedsLast = server.hasArg("EI");
strip.setReverseMode(reverseMode);
if (server.hasArg("WO"))
{
Expand Down
69 changes: 40 additions & 29 deletions wled00/wled05_init.ino
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,19 @@

void wledInit()
{
EEPROM.begin(EEPSIZE);
if (!EEPROM.read(397)) strip.init(); //quick init

Serial.begin(115200);

#ifdef USEFS
SPIFFS.begin();
{
Dir dir = SPIFFS.openDir("/");
while (dir.next()) {
String fileName = dir.fileName();
size_t fileSize = dir.fileSize();
#ifdef DEBUG
Serial.printf("FS File: %s, size: %s\n", fileName.c_str(), formatBytes(fileSize).c_str());
#endif
}
DEBUG_PRINTF("\n");
}
#endif

DEBUG_PRINTLN("Init EEPROM");
EEPROM.begin(EEPSIZE);
DEBUG_PRINTLN("Load EEPROM");
loadSettingsFromEEPROM(true);
DEBUG_PRINT("CC: SSID: ");
if (!initLedsLast) initStrip();
DEBUG_PRINT("C-SSID: ");
DEBUG_PRINT(clientSSID);
buildCssColorString();
userBeginPreConnection();
Expand Down Expand Up @@ -140,7 +132,7 @@ void wledInit()
});

server.on("/reset", HTTP_GET, [](){
serveMessage(200,"Rebooting now...","(takes ~20 seconds, wait for auto-redirect)",139);
serveMessage(200,"Rebooting now...","(takes ~20 seconds, wait for auto-redirect)",79);
reset();
});

Expand Down Expand Up @@ -301,10 +293,15 @@ void wledInit()
ArduinoOTA.begin();
}

if (initLedsLast) initStrip();
userBegin();
if (macroBoot>0) applyMacro(macroBoot);
}

// Initialize NeoPixel Strip
strip.init();
void initStrip()
{
// Initialize NeoPixel Strip and button
if (initLedsLast) strip.init();
strip.setLedCount(ledCount);
strip.setReverseMode(reverseMode);
strip.setColor(0);
Expand All @@ -314,7 +311,6 @@ void wledInit()
pinMode(buttonPin, INPUT_PULLUP);

if (bootPreset>0) applyPreset(bootPreset, turnOnAtBoot, true, true);
if (macroBoot>0) applyMacro(macroBoot);
colorUpdated(0);
if(digitalRead(buttonPin) == LOW) buttonEnabled = false; //disable button if it is "pressed" unintentionally
}
Expand All @@ -331,17 +327,32 @@ void initCon()
int fail_count = 0;
if (clientSSID.length() <1 || clientSSID.equals("Your_Network")) fail_count = apWaitTimeSecs*2;
WiFi.begin(clientSSID.c_str(), clientPass.c_str());
while(WiFi.status() != WL_CONNECTED) {
delay(500);
DEBUG_PRINTLN("C_NC");
fail_count++;
if (!recoveryAPDisabled && fail_count > apWaitTimeSecs*2)
unsigned long lastTry = 0;
bool con = false;
while(!con)
{
yield();
if (!initLedsLast)
{
WiFi.disconnect();
DEBUG_PRINTLN("Can't connect. Opening AP...");
onlyAP = true;
initAP();
return;
handleTransitions();
handleButton();
handleOverlays();
if (briT) strip.service();
}
if (millis()-lastTry > 499) {
con = (WiFi.status() == WL_CONNECTED);
if (con) DEBUG_PRINTLN("rofl");
lastTry = millis();
DEBUG_PRINTLN("C_NC");
if (!recoveryAPDisabled && fail_count > apWaitTimeSecs*2)
{
WiFi.disconnect();
DEBUG_PRINTLN("Can't connect. Opening AP...");
onlyAP = true;
initAP();
return;
}
fail_count++;
}
}
}
Expand Down
4 changes: 3 additions & 1 deletion wled00/wled07_notify.ino
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,14 @@ void notify(byte callMode, bool followUp=false)
udpOut[8] = effectCurrent;
udpOut[9] = effectSpeed;
udpOut[10] = white;
udpOut[11] = 3; //compatibilityVersionByte: 0: old 1: supports white 2: supports secondary color 3: supports FX intensity, 24 byte packet
udpOut[11] = 4; //compatibilityVersionByte: 0: old 1: supports white 2: supports secondary color 3: supports FX intensity, 24 byte packet 4: supports transitionDelay
udpOut[12] = colSec[0];
udpOut[13] = colSec[1];
udpOut[14] = colSec[2];
udpOut[15] = whiteSec;
udpOut[16] = effectIntensity;
udpOut[17] = (transitionDelay >> 0) & 0xFF;
udpOut[18] = (transitionDelay >> 8) & 0xFF;

IPAddress broadcastIp;
broadcastIp = ~WiFi.subnetMask() | WiFi.gatewayIP();
Expand Down
3 changes: 2 additions & 1 deletion wled00/wled10_ntp.ino
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ void handleNetworkTime()

void sendNTPPacket()
{
WiFi.hostByName(ntpServerName, ntpServerIP);
const char* ntpsrv = ntpServerName.c_str();
WiFi.hostByName(ntpsrv, ntpServerIP);
DEBUG_PRINTLN("send NTP packet");

memset(ntpPacketBuffer, 0, NTP_PACKET_SIZE);
Expand Down
4 changes: 2 additions & 2 deletions wled00/wled11_ol.ino
Original file line number Diff line number Diff line change
Expand Up @@ -118,19 +118,19 @@ void _nixieNumber(int number, int dur)

void handleOverlays()
{
if (overlayCurrent == 0) return;

if (millis() - overlayRefreshedTime > overlayRefreshMs)
{
initCronixie();
updateLocalTime();
switch (overlayCurrent)
{
case 0: break;//no overlay
case 1: _overlaySolid(); break;//solid secondary color
case 2: _overlayAnalogClock(); break;//2 analog clock
case 3: _overlayNixieClock(); break;//nixie 1-digit
case 4: _overlayCronixie();//Diamex cronixie clock kit
}
if (!countdownMode || overlayCurrent < 2) checkCountdown(); //countdown macro activation must work
overlayRefreshedTime = millis();
}
}
Expand Down
2 changes: 1 addition & 1 deletion wled00/wled15_hue.ino
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ bool sendHuePoll(bool sAuth)
st = false;
}
if (!st){ //error
if (hueFailCount<7) huePollIntervalMsTemp*=2; // only poll every 5min when unable to connect
if (huePollIntervalMsTemp<300000) huePollIntervalMsTemp*=2; // only poll every ~5min when unable to connect
hueFailCount++;
if (hueFailCount > 150) huePollingEnabled = false; //disable after many hours offline
}
Expand Down

0 comments on commit 89afdd2

Please sign in to comment.