Merge branch 'master' of github.com:Aircoookie/WLED into disable_n_leds_for_all_fx

 Conflicts:
	wled00/data/settings_leds.htm
This commit is contained in:
emerrill 2019-11-29 10:56:59 -07:00
commit 4729bce16c
11 changed files with 265 additions and 34 deletions

View File

@ -6,11 +6,11 @@ If you have created an usermod that you believe is useful (for example to suppor
In order for other people to be able to have fun with your usermod, please keep these points in mind: In order for other people to be able to have fun with your usermod, please keep these points in mind:
- Create a folder in this folder with a descriptive name (for example `usermod_ds18b20_temp_sensor_mqtt`) - Create a folder in this folder with a descriptive name (for example `usermod_ds18b20_temp_sensor_mqtt`)
- Include your custom `wled06_usermod.ino` file - Include your custom `wled06_usermod.ino` file
- If your usermod requieres changes to other WLED files, please write a `readme.md` outlining the steps one has to take to use the usermod - If your usermod requieres changes to other WLED files, please write a `readme.md` outlining the steps one has to take to use the usermod
- Create a pull request! - Create a pull request!
- If your feature is useful for the majority of WLED users, I will consider adding it to the base code! - If your feature is useful for the majority of WLED users, I will consider adding it to the base code!
While I do my best to not break too much, keep in mind that as WLED is being updated, usermods might break. While I do my best to not break too much, keep in mind that as WLED is being updated, usermods might break.
I am not actively maintaining any usermod in this directory, that is your responsibility as the creator of the usermod. I am not actively maintaining any usermod in this directory, that is your responsibility as the creator of the usermod.

View File

@ -0,0 +1,35 @@
# SSD1306 128x32 OLED via I2C with u8g2
This usermod allows to connect 128x32 Oled display to WLED controlled and show
the next information:
- Current SSID
- IP address if obtained
* in AP mode and turned off lightning AP password is shown
- Current effect
- Current palette
- On/Off icon (sun/moon)
## Hardware
![Hardware connection](assets/hw_connection.png)
## Requirements
Functionality checked with:
- commit 095429a7df4f9e2b34dd464f7bbfd068df6558eb
- Wemos d1 mini
- PlatformIO
- Generic SSD1306 128x32 I2C OLED display from aliexpress
### Platformio
Add `U8g2@~2.27.2` dependency to `lib_deps_external` under `[common]` section in `platformio.ini`:
```ini
# platformio.ini
...
[common]
...
lib_deps_external =
...
U8g2@~2.27.2
...
```
### Arduino IDE
Install library `U8g2 by oliver` in `Tools | Include Library | Manage libraries` menu.

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

View File

@ -0,0 +1,149 @@
#include <U8x8lib.h> // from https://github.com/olikraus/u8g2/
// If display does not work or looks corrupted check the
// constructor reference:
// https://github.com/olikraus/u8g2/wiki/u8x8setupcpp
// or check the gallery:
// https://github.com/olikraus/u8g2/wiki/gallery
U8X8_SSD1306_128X32_UNIVISION_HW_I2C u8x8(U8X8_PIN_NONE, 5,
4); // Pins are Reset, SCL, SDA
// gets called once at boot. Do all initialization that doesn't depend on
// network here
void userSetup() {
u8x8.begin();
u8x8.setPowerSave(0);
u8x8.setFont(u8x8_font_chroma48medium8_r);
u8x8.drawString(0, 0, "Loading...");
}
// gets called every time WiFi is (re-)connected. Initialize own network
// interfaces here
void userConnected() {}
// needRedraw marks if redraw is required to prevent often redrawing.
bool needRedraw = true;
// Next variables hold the previous known values to determine if redraw is
// required.
String knownSsid = "";
IPAddress knownIp;
uint8_t knownBrightness = 0;
uint8_t knownMode = 0;
uint8_t knownPalette = 0;
long lastUpdate = 0;
// How often we are redrawing screen
#define USER_LOOP_REFRESH_RATE_MS 5000
void userLoop() {
// Check if we time interval for redrawing passes.
if (millis() - lastUpdate < USER_LOOP_REFRESH_RATE_MS) {
return;
}
lastUpdate = millis();
// Check if values which are shown on display changed from the last tiem.
if ((apActive == true ? String(apSSID) : WiFi.SSID()) != knownSsid) {
needRedraw = true;
} else if (knownIp != (apActive ? IPAddress(4, 3, 2, 1) : WiFi.localIP())) {
needRedraw = true;
} else if (knownBrightness != bri) {
needRedraw = true;
} else if (knownMode != strip.getMode()) {
needRedraw = true;
} else if (knownPalette != strip.getSegment(0).palette) {
needRedraw = true;
}
if (!needRedraw) {
return;
}
needRedraw = false;
// Update last known values.
knownSsid = apActive ? WiFi.softAPSSID() : WiFi.SSID();
knownIp = apActive ? IPAddress(4, 3, 2, 1) : WiFi.localIP();
knownBrightness = bri;
knownMode = strip.getMode();
knownPalette = strip.getSegment(0).palette;
u8x8.clear();
u8x8.setFont(u8x8_font_chroma48medium8_r);
// First row with Wifi name
u8x8.setCursor(1, 0);
u8x8.print(ssid.substring(0, u8x8.getCols() > 1 ? u8x8.getCols() - 2 : 0));
// Print `~` char to indicate that SSID is longer, than owr dicplay
if (ssid.length() > u8x8.getCols())
u8x8.print("~");
// Second row with IP or Psssword
u8x8.setCursor(1, 1);
// Print password in AP mode and if led is OFF.
if (apActive && bri == 0)
u8x8.print(apPass);
else
u8x8.print(ip);
// Third row with mode name
u8x8.setCursor(2, 2);
uint8_t qComma = 0;
bool insideQuotes = false;
uint8_t printedChars = 0;
char singleJsonSymbol;
// Find the mode name in JSON
for (size_t i = 0; i < strlen_P(JSON_mode_names); i++) {
singleJsonSymbol = pgm_read_byte_near(JSON_mode_names + i);
switch (singleJsonSymbol) {
case '"':
insideQuotes = !insideQuotes;
break;
case '[':
case ']':
break;
case ',':
qComma++;
default:
if (!insideQuotes || (qComma != knownMode))
break;
u8x8.print(singleJsonSymbol);
printedChars++;
}
if ((qComma > knownMode) || (printedChars > u8x8.getCols() - 2))
break;
}
// Fourth row with palette name
u8x8.setCursor(2, 3);
qComma = 0;
insideQuotes = false;
printedChars = 0;
// Looking for palette name in JSON.
for (size_t i = 0; i < strlen_P(JSON_palette_names); i++) {
singleJsonSymbol = pgm_read_byte_near(JSON_palette_names + i);
switch (singleJsonSymbol) {
case '"':
insideQuotes = !insideQuotes;
break;
case '[':
case ']':
break;
case ',':
qComma++;
default:
if (!insideQuotes || (qComma != knownPalette))
break;
u8x8.print(singleJsonSymbol);
printedChars++;
}
if ((qComma > knownMode) || (printedChars > u8x8.getCols() - 2))
break;
}
u8x8.setFont(u8x8_font_open_iconic_embedded_1x1);
u8x8.drawGlyph(0, 0, 80); // wifi icon
u8x8.drawGlyph(0, 1, 68); // home icon
u8x8.setFont(u8x8_font_open_iconic_weather_2x2);
u8x8.drawGlyph(0, 2, 66 + (bri > 0 ? 3 : 0)); // sun/moon icon
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -16,14 +16,14 @@
//You are required to disable over-the-air updates: //You are required to disable over-the-air updates:
//#define WLED_DISABLE_OTA //#define WLED_DISABLE_OTA
//You need to choose 1-2 of these features to disable: //You need to choose some of these features to disable:
//#define WLED_DISABLE_ALEXA //#define WLED_DISABLE_ALEXA
//#define WLED_DISABLE_BLYNK //#define WLED_DISABLE_BLYNK
//#define WLED_DISABLE_CRONIXIE //#define WLED_DISABLE_CRONIXIE
//#define WLED_DISABLE_HUESYNC //#define WLED_DISABLE_HUESYNC
//#define WLED_DISABLE_INFRARED //there is no pin left for this on ESP8266-01 //#define WLED_DISABLE_INFRARED //there is no pin left for this on ESP8266-01
//#define WLED_DISABLE_MOBILE_UI //#define WLED_DISABLE_MOBILE_UI
#define WLED_ENABLE_ADALIGHT //only saves about 500b
#define WLED_DISABLE_FILESYSTEM //SPIFFS is not used by any WLED feature yet #define WLED_DISABLE_FILESYSTEM //SPIFFS is not used by any WLED feature yet
//#define WLED_ENABLE_FS_SERVING //Enable sending html file from SPIFFS before serving progmem version //#define WLED_ENABLE_FS_SERVING //Enable sending html file from SPIFFS before serving progmem version
@ -437,7 +437,7 @@ AsyncMqttClient* mqtt = NULL;
void serveMessage(AsyncWebServerRequest*,uint16_t,String,String,byte); void serveMessage(AsyncWebServerRequest*,uint16_t,String,String,byte);
void handleE131Packet(e131_packet_t*, IPAddress); void handleE131Packet(e131_packet_t*, IPAddress);
#define E131_MAX_UNIVERSE_COUNT 7 #define E131_MAX_UNIVERSE_COUNT 9
//udp interface objects //udp interface objects
WiFiUDP notifierUdp, rgbUdp; WiFiUDP notifierUdp, rgbUdp;

View File

@ -1,40 +1,87 @@
/* /*
* Utility for SPIFFS filesystem & Serial console * Utility for SPIFFS filesystem & Serial console
*/ */
enum class AdaState {
Header_A,
Header_d,
Header_a,
Header_CountHi,
Header_CountLo,
Header_CountCheck,
Data_Red,
Data_Green,
Data_Blue
};
void handleSerial() void handleSerial()
{ {
if (Serial.available() > 0) //support for Adalight protocol to high-speed control LEDs over serial #ifdef WLED_ENABLE_ADALIGHT
{ static auto state = AdaState::Header_A;
if (!Serial.find("Ada")) return; static uint16_t count = 0;
static uint16_t pixel = 0;
static byte check = 0x00;
static byte red = 0x00;
static byte green = 0x00;
static bool changed = false;
while (Serial.available() > 0)
{
byte next = Serial.read();
switch (state) {
case AdaState::Header_A:
if (next == 'A') state = AdaState::Header_d;
break;
case AdaState::Header_d:
if (next == 'd') state = AdaState::Header_a;
else state = AdaState::Header_A;
break;
case AdaState::Header_a:
if (next == 'a') state = AdaState::Header_CountHi;
else state = AdaState::Header_A;
break;
case AdaState::Header_CountHi:
pixel = 0;
count = next * 0x100;
check = next;
state = AdaState::Header_CountLo;
break;
case AdaState::Header_CountLo:
count += next + 1;
check = check ^ next ^ 0x55;
state = AdaState::Header_CountCheck;
break;
case AdaState::Header_CountCheck:
if (check == next) state = AdaState::Data_Red;
else state = AdaState::Header_A;
break;
case AdaState::Data_Red:
red = next;
state = AdaState::Data_Green;
break;
case AdaState::Data_Green:
green = next;
state = AdaState::Data_Blue;
break;
case AdaState::Data_Blue:
byte blue = next;
changed = true;
setRealtimePixel(pixel++, red, green, blue, 0);
if (--count > 0) state = AdaState::Data_Red;
else state = AdaState::Header_A;
break;
}
}
if (changed)
{
if (!realtimeActive && bri == 0) strip.setBrightness(briLast); if (!realtimeActive && bri == 0) strip.setBrightness(briLast);
arlsLock(realtimeTimeoutMs); arlsLock(realtimeTimeoutMs);
yield(); yield();
byte hi = Serial.read();
byte ledc = Serial.read();
byte chk = Serial.read();
if(chk != (hi ^ ledc ^ 0x55)) return;
if (ledCount < ledc) ledc = ledCount;
byte sc[3]; int t =-1; int to = 0;
for (int i=0; i < ledc; i++)
{
for (byte j=0; j<3; j++)
{
while (Serial.peek()<0) //no data yet available
{
yield();
to++;
if (to>15) {strip.show(); return;} //unexpected end of transmission
}
to = 0;
sc[j] = Serial.read();
}
setRealtimePixel(i,sc[0],sc[1],sc[2],0);
}
strip.show(); strip.show();
changed = false;
} }
#endif
} }