diff --git a/platformio.ini b/platformio.ini
index 7b50f693..5002cc89 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -417,11 +417,21 @@ lib_ignore =
[env:wemos_shield_esp32]
board = esp32dev
platform = espressif32@3.2
-upload_port = /dev/cu.SLAB_USBtoUART
-monitor_port = /dev/cu.SLAB_USBtoUART
upload_speed = 460800
build_unflags = ${common.build_unflags}
-build_flags = ${common.build_flags_esp32} -D LEDPIN=16 -D RLYPIN=19 -D BTNPIN=17
+build_flags = ${common.build_flags_esp32}
+ -D LEDPIN=16
+ -D RLYPIN=19
+ -D BTNPIN=17
+ -D UWLED_USE_MY_CONFIG
+; -D USERMOD_DALLASTEMPERATURE
+; -D USERMOD_DALLASTEMPERATURE_CELCIUS
+; -D USERMOD_FOUR_LINE_DISPLAY
+; -D TEMPERATURE_PIN=21
+lib_deps = ${env.lib_deps}
+; OneWire@~2.3.5
+; milesburton/DallasTemperature@^3.9.0
+; U8g2@~2.27.2
lib_ignore =
ESPAsyncTCP
ESPAsyncUDP
@@ -511,3 +521,4 @@ monitor_filters = esp32_exception_decoder
lib_ignore =
ESPAsyncTCP
ESPAsyncUDP
+
\ No newline at end of file
diff --git a/readme.md b/readme.md
index 9cee21f3..c3f5987e 100644
--- a/readme.md
+++ b/readme.md
@@ -9,7 +9,6 @@
-
# Welcome to my project WLED! ✨
A fast and feature-rich implementation of an ESP8266/ESP32 webserver to control NeoPixel (WS2812B, WS2811, SK6812) LEDs or also SPI based chipsets like the WS2801 and APA102!
diff --git a/usermods/ST7789_display/README.md b/usermods/ST7789_display/README.md
new file mode 100644
index 00000000..653fdd75
--- /dev/null
+++ b/usermods/ST7789_display/README.md
@@ -0,0 +1,72 @@
+# ST7789 TFT IPS Color display 240x240pxwith ESP32 boards
+
+This usermod allow to use 240x240 display to display following:
+
+* Network SSID;
+* IP address;
+* Brightness;
+* Chosen effect;
+* Chosen palette;
+* Estimated current in mA;
+
+## Hardware
+
+***
+![Hardware](images/ST7789_guide.jpg)
+
+## Library used
+
+[Bodmer/TFT_eSPI](https://github.com/Bodmer/TFT_eSPI)
+
+## Setup
+
+***
+
+### Platformio.ini changes
+
+In the `platformio.ini` file, uncomment the `TFT_eSPI` line within the [common] section, under `lib_deps`:
+
+```ini
+# platformio.ini
+...
+[common]
+...
+lib_deps =
+ ...
+ #For use of the TTGO T-Display ESP32 Module with integrated TFT display uncomment the following line
+ #TFT_eSPI
+...
+```
+
+Also, while in the `platformio.ini` file, you must change the environment setup to build for just the esp32dev platform as follows:
+
+Add lines to section:
+
+```ini
+default_envs = esp32dev
+build_flags = ${common.build_flags_esp32}
+ -D USERMOD_ST7789_DISPLAY
+
+```
+
+Save the `platformio.ini` file. Once this is saved, the required library files should be automatically downloaded for modifications in a later step.
+
+### TFT_eSPI Library Adjustments
+
+We need to modify a file in the `TFT_eSPI` library. If you followed the directions to modify and save the `platformio.ini` file above, the `User_Setup_Select.h` file can be found in the `/.pio/libdeps/esp32dev/TFT_eSPI` folder.
+
+Modify the `User_Setup_Select.h` file as follows:
+
+* Comment out the following line (which is the 'default' setup file):
+
+```ini
+//#include // Default setup is root library folder
+```
+
+* Add following line:
+
+```ini
+#include // Setup file for ESP32 ST7789V SPI bus TFT
+```
+
+* Copy file `"Setup_ST7789_Display.h"` from usermod folder to `/.pio/libdeps/esp32dev/TFT_eSPI/User_Setups`
diff --git a/usermods/ST7789_display/ST7789_display.h b/usermods/ST7789_display/ST7789_display.h
new file mode 100644
index 00000000..bd501d08
--- /dev/null
+++ b/usermods/ST7789_display/ST7789_display.h
@@ -0,0 +1,350 @@
+// Credits to @mrVanboy, @gwaland and my dearest friend @westward
+// Also for @spiff72 for usermod TTGO-T-Display
+// 210217
+#pragma once
+
+#include "wled.h"
+#include
+#include
+
+#define USERMOD_ST7789_DISPLAY 97
+
+#ifndef TFT_DISPOFF
+#define TFT_DISPOFF 0x28
+#endif
+
+#ifndef TFT_SLPIN
+#define TFT_SLPIN 0x10
+#endif
+
+#define TFT_MOSI 21
+#define TFT_SCLK 22
+#define TFT_DC 18
+#define TFT_RST 5
+#define TFT_BL 26 // Display backlight control pin
+
+TFT_eSPI tft = TFT_eSPI(240, 240); // Invoke custom library
+
+// How often we are redrawing screen
+#define USER_LOOP_REFRESH_RATE_MS 1000
+
+
+//class name. Use something descriptive and leave the ": public Usermod" part :)
+class St7789DisplayUsermod : public Usermod {
+ private:
+ //Private class members. You can declare variables and functions only accessible to your usermod here
+ unsigned long lastTime = 0;
+
+ bool displayTurnedOff = false;
+ long lastRedraw = 0;
+ // 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;
+ uint8_t tftcharwidth = 19; // Number of chars that fit on screen with text size set to 2
+ long lastUpdate = 0;
+
+ public:
+ //Functions called by WLED
+
+ /*
+ * setup() is called once at boot. WiFi is not yet connected at this point.
+ * You can use it to initialize variables, sensors or similar.
+ */
+ void setup()
+ {
+ tft.init();
+ tft.setRotation(0); //Rotation here is set up for the text to be readable with the port on the left. Use 1 to flip.
+ tft.fillScreen(TFT_BLACK);
+ tft.setTextColor(TFT_RED);
+ tft.setCursor(60, 100);
+ tft.setTextDatum(MC_DATUM);
+ tft.setTextSize(2);
+ tft.print("Loading...");
+ if (TFT_BL > 0)
+ { // TFT_BL has been set in the TFT_eSPI library
+ pinMode(TFT_BL, OUTPUT); // Set backlight pin to output mode
+ digitalWrite(TFT_BL, HIGH); // Turn backlight on.
+ }
+ }
+
+ /*
+ * connected() is called every time the WiFi is (re)connected
+ * Use it to initialize network interfaces
+ */
+ void connected() {
+ //Serial.println("Connected to WiFi!");
+ }
+
+ /*
+ * loop() is called continuously. Here you can check for events, read sensors, etc.
+ *
+ * Tips:
+ * 1. You can use "if (WLED_CONNECTED)" to check for a successful network connection.
+ * Additionally, "if (WLED_MQTT_CONNECTED)" is available to check for a connection to an MQTT broker.
+ *
+ * 2. Try to avoid using the delay() function. NEVER use delays longer than 10 milliseconds.
+ * Instead, use a timer check as shown here.
+ */
+ void loop() {
+// Check if we time interval for redrawing passes.
+ if (millis() - lastUpdate < USER_LOOP_REFRESH_RATE_MS)
+ {
+ return;
+ }
+ lastUpdate = millis();
+
+// Turn off display after 5 minutes with no change.
+ if(!displayTurnedOff && millis() - lastRedraw > 5*60*1000)
+ {
+ digitalWrite(TFT_BL, LOW); // Turn backlight off.
+ displayTurnedOff = true;
+ }
+
+// Check if values which are shown on display changed from the last time.
+ if (((apActive) ? 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;
+
+ if (displayTurnedOff)
+ {
+ digitalWrite(TFT_BL, TFT_BACKLIGHT_ON); // Turn backlight on.
+ displayTurnedOff = false;
+ }
+ lastRedraw = millis();
+
+// Update last known values.
+ #if defined(ESP8266)
+ knownSsid = apActive ? WiFi.softAPSSID() : WiFi.SSID();
+ #else
+ knownSsid = WiFi.SSID();
+ #endif
+ knownIp = apActive ? IPAddress(4, 3, 2, 1) : WiFi.localIP();
+ knownBrightness = bri;
+ knownMode = strip.getMode();
+ knownPalette = strip.getSegment(0).palette;
+
+ tft.fillScreen(TFT_BLACK);
+ tft.setTextSize(2);
+// First row with Wifi name
+ tft.setTextColor(TFT_SILVER);
+ tft.setCursor(3, 40);
+ tft.print(knownSsid.substring(0, tftcharwidth > 1 ? tftcharwidth - 1 : 0));
+// Print `~` char to indicate that SSID is longer, than our dicplay
+ if (knownSsid.length() > tftcharwidth)
+ tft.print("~");
+
+// Second row with AP IP and Password or IP
+ tft.setTextColor(TFT_GREEN);
+ tft.setTextSize(2);
+ tft.setCursor(3, 64);
+// Print AP IP and password in AP mode or knownIP if AP not active.
+
+ if (apActive)
+ {
+ tft.setTextColor(TFT_YELLOW);
+ tft.print("AP IP: ");
+ tft.print(knownIp);
+ tft.setCursor(3,86);
+ tft.setTextColor(TFT_YELLOW);
+ tft.print("AP Pass:");
+ tft.print(apPass);
+ }
+ else
+ {
+ tft.setTextColor(TFT_GREEN);
+ tft.print("IP: ");
+ tft.print(knownIp);
+ tft.setCursor(3,86);
+ //tft.print("Signal Strength: ");
+ //tft.print(i.wifi.signal);
+ tft.setTextColor(TFT_WHITE);
+ tft.print("Bri: ");
+ tft.print(((float(bri)/255)*100),0);
+ tft.print("%");
+ }
+
+// Third row with mode name
+ tft.setCursor(3, 108);
+ 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;
+ tft.setTextColor(TFT_MAGENTA);
+ tft.print(singleJsonSymbol);
+ printedChars++;
+ }
+ if ((qComma > knownMode) || (printedChars > tftcharwidth - 1))
+ break;
+ }
+// Fourth row with palette name
+ tft.setTextColor(TFT_YELLOW);
+ tft.setCursor(3, 130);
+ 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;
+ tft.print(singleJsonSymbol);
+ printedChars++;
+ }
+// The following is modified from the code from the u8g2/u8g8 based code (knownPalette was knownMode)
+ if ((qComma > knownPalette) || (printedChars > tftcharwidth - 1))
+ break;
+ }
+// Fifth row with estimated mA usage
+ tft.setTextColor(TFT_SILVER);
+ tft.setCursor(3, 152);
+// Print estimated milliamp usage (must specify the LED type in LED prefs for this to be a reasonable estimate).
+ tft.print("Current: ");
+ tft.print(strip.currentMilliamps);
+ tft.print("mA");
+ }
+ /*
+ * addToJsonInfo() can be used to add custom entries to the /json/info part of the JSON API.
+ * Creating an "u" object allows you to add custom key/value pairs to the Info section of the WLED web UI.
+ * Below it is shown how this could be used for e.g. a light sensor
+ */
+ /*
+ void addToJsonInfo(JsonObject& root)
+ {
+ int reading = 20;
+ //this code adds "u":{"Light":[20," lux"]} to the info object
+ JsonObject user = root["u"];
+ if (user.isNull()) user = root.createNestedObject("u");
+
+ JsonArray lightArr = user.createNestedArray("Light"); //name
+ lightArr.add(reading); //value
+ lightArr.add(" lux"); //unit
+ }
+ */
+
+
+ /*
+ * addToJsonState() can be used to add custom entries to the /json/state part of the JSON API (state object).
+ * Values in the state object may be modified by connected clients
+ */
+ void addToJsonState(JsonObject& root)
+ {
+ //root["user0"] = userVar0;
+ }
+
+
+ /*
+ * readFromJsonState() can be used to receive data clients send to the /json/state part of the JSON API (state object).
+ * Values in the state object may be modified by connected clients
+ */
+ void readFromJsonState(JsonObject& root)
+ {
+ userVar0 = root["user0"] | userVar0; //if "user0" key exists in JSON, update, else keep old value
+ //if (root["bri"] == 255) Serial.println(F("Don't burn down your garage!"));
+ }
+
+
+ /*
+ * addToConfig() can be used to add custom persistent settings to the cfg.json file in the "um" (usermod) object.
+ * It will be called by WLED when settings are actually saved (for example, LED settings are saved)
+ * If you want to force saving the current state, use serializeConfig() in your loop().
+ *
+ * CAUTION: serializeConfig() will initiate a filesystem write operation.
+ * It might cause the LEDs to stutter and will cause flash wear if called too often.
+ * Use it sparingly and always in the loop, never in network callbacks!
+ *
+ * addToConfig() will also not yet add your setting to one of the settings pages automatically.
+ * To make that work you still have to add the setting to the HTML, xml.cpp and set.cpp manually.
+ *
+ * I highly recommend checking out the basics of ArduinoJson serialization and deserialization in order to use custom settings!
+ */
+ void addToConfig(JsonObject& root)
+ {
+ JsonObject top = root.createNestedObject("exampleUsermod");
+ top["great"] = userVar0; //save this var persistently whenever settings are saved
+ }
+
+
+ /*
+ * readFromConfig() can be used to read back the custom settings you added with addToConfig().
+ * This is called by WLED when settings are loaded (currently this only happens once immediately after boot)
+ *
+ * readFromConfig() is called BEFORE setup(). This means you can use your persistent values in setup() (e.g. pin assignments, buffer sizes),
+ * but also that if you want to write persistent values to a dynamic buffer, you'd need to allocate it here instead of in setup.
+ * If you don't know what that is, don't fret. It most likely doesn't affect your use case :)
+ */
+ void readFromConfig(JsonObject& root)
+ {
+ JsonObject top = root["top"];
+ userVar0 = top["great"] | 42; //The value right of the pipe "|" is the default value in case your setting was not present in cfg.json (e.g. first boot)
+ }
+
+
+ /*
+ * getId() allows you to optionally give your V2 usermod an unique ID (please define it in const.h!).
+ * This could be used in the future for the system to determine whether your usermod is installed.
+ */
+ uint16_t getId()
+ {
+ return USERMOD_ST7789_DISPLAY;
+ }
+
+ //More methods can be added in the future, this example will then be extended.
+ //Your usermod will remain compatible as it does not need to implement all methods from the Usermod base class!
+};
\ No newline at end of file
diff --git a/usermods/ST7789_display/Setup_ST7789_Display.h b/usermods/ST7789_display/Setup_ST7789_Display.h
new file mode 100644
index 00000000..26d5c17f
--- /dev/null
+++ b/usermods/ST7789_display/Setup_ST7789_Display.h
@@ -0,0 +1,39 @@
+// Setup for the ESP32 board with 1.5" 240x240 display
+
+// See SetupX_Template.h for all options available
+
+#define ST7789_DRIVER
+#define TFT_SDA_READ // Display has a bidirectionsl SDA pin
+
+#define TFT_WIDTH 240
+#define TFT_HEIGHT 240
+
+#define CGRAM_OFFSET // Library will add offsets required
+
+//#define TFT_MISO -1
+
+#define TFT_MOSI 21
+#define TFT_SCLK 22
+//#define TFT_CS 5
+#define TFT_DC 18
+#define TFT_RST 5
+
+#define TFT_BL 26 // Display backlight control pin
+
+#define TFT_BACKLIGHT_ON HIGH // HIGH or LOW are options
+
+#define LOAD_GLCD
+#define LOAD_FONT2
+#define LOAD_FONT4
+#define LOAD_FONT6
+#define LOAD_FONT7
+#define LOAD_FONT8
+#define LOAD_GFXFF
+
+//#define SMOOTH_FONT
+
+//#define SPI_FREQUENCY 27000000
+ #define SPI_FREQUENCY 40000000 // Maximum for ILI9341
+
+
+#define SPI_READ_FREQUENCY 6000000 // 6 MHz is the maximum SPI read speed for the ST7789V
\ No newline at end of file
diff --git a/usermods/ST7789_display/images/ST7789_Guide.jpg b/usermods/ST7789_display/images/ST7789_Guide.jpg
new file mode 100644
index 00000000..80fee420
Binary files /dev/null and b/usermods/ST7789_display/images/ST7789_Guide.jpg differ