diff --git a/usermods/TTGO-T-Display/README.md b/usermods/TTGO-T-Display/README.md index 439f9832dd..78eddc8c5b 100644 --- a/usermods/TTGO-T-Display/README.md +++ b/usermods/TTGO-T-Display/README.md @@ -15,6 +15,8 @@ I have designed a 3D printed case around this board and an ["ElectroCookie"](htt Based on a rework of the ssd1306_i2c_oled_u8g2 usermod from the WLED repo. +In December 2024, I made some changes to fix compilation errors, and modified the platformio_override.ini file to include ALL changes needed (no more need to edit the origiginal "stock" platformio.ini file). I am also forcing an older version of the TFT_eSPI library. + ## Hardware ![Hardware](assets/ttgo_hardware1.png) ![Hardware](assets/ttgo-tdisplay-enclosure1a.png) @@ -37,55 +39,15 @@ Functionality checked with: * As with all usermods, copy the usermod.cpp file from the TTGO-T-Display usermod folder to the wled00 folder (replacing the default usermod.cpp file). ## Platformio Requirements -### Platformio.ini changes -Under the root folder of the project, 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 -... -``` - -In the `platformio.ini` file, you must change the environment setup to build for just the esp32dev platform as follows: -Comment out the line described below: -```ini -# Release binaries -; default_envs = nodemcuv2, esp8266_2m, esp01_1m_full, esp32dev, esp32_eth, esp32s2_saola, esp32c3 -``` -and uncomment the following line in the 'Single binaries' section: -```ini -default_envs = esp32dev -``` -Save the `platformio.ini` file. Once saved, the required library files should be automatically downloaded for modifications in a later step. +### Platformio_override.ini (added) +Copy the `platformio_override.ini` file which is contained in the `usermods/TTGO-T-Display/` folder into the root of your project folder. This file contains an override that remaps the button pin of WLED to use the on-board button to the right of the USB-C connector (when viewed with the port oriented downward - see hardware photo). -### Platformio_overrides.ini (added) -Copy the `platformio_overrides.ini` file which is contained in the `usermods/TTGO-T-Display/` folder into the root of your project folder. This file contains an override that remaps the button pin of WLED to use the on-board button to the right of the USB-C connector (when viewed with the port oriented downward - see hardware photo). - -### TFT_eSPI Library Adjustments (board selection) -You need to modify a file in the `TFT_eSPI` library to select the correct board. 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_ID1559` folder. +### Platformio.ini changes +Once the platformio_override.ini file has been copied as described above, the platformio.ini file isn't actually changed, but it is helpful to save the platformio.ini file in the VS Code application. This should trigger the download of the library dependencies. -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 -``` -* Uncomment the following line (which points to the setup file for the TTGO T-Display): -```ini -#include // Setup file for ESP32 and TTGO T-Display ST7789V SPI bus TFT -``` +### Change to the WLED_T-Display environment +This should appear as an option in the bottom toolbar. -Build the file. If you see a failure like this: -```ini -xtensa-esp32-elf-g++: error: wled00\wled00.ino.cpp: No such file or directory -xtensa-esp32-elf-g++: fatal error: no input files -``` -try building again. Sometimes this happens on the first build attempt and subsequent attempts build correctly. +Once the compilation is done and loaded onto the TTGO T-Display module, the display should show "Loading...", and then it will show the IP of the WLED access point. -## Arduino IDE -- UNTESTED diff --git a/usermods/TTGO-T-Display/library.json b/usermods/TTGO-T-Display/library.json new file mode 100644 index 0000000000..812478fce9 --- /dev/null +++ b/usermods/TTGO-T-Display/library.json @@ -0,0 +1,10 @@ +{ + "name:": "TTGO-T-Display", + "dependencies": { + "TFT_eSPI" : "https://github.com/Bodmer/TFT_eSPI.git#5793878" + }, + "build": { + "extraScript": "set_build_flags.py", + "libArchive": false + } +} diff --git a/usermods/TTGO-T-Display/platformio_override.ini b/usermods/TTGO-T-Display/platformio_override.ini index 7e42d9a54a..b85b450e51 100644 --- a/usermods/TTGO-T-Display/platformio_override.ini +++ b/usermods/TTGO-T-Display/platformio_override.ini @@ -1,8 +1,39 @@ -[env:esp32dev] -build_flags = ${common.build_flags_esp32} -; PIN defines - uncomment and change, if needed: -; -D LEDPIN=2 - -D BTNPIN=35 +# Example PlatformIO Project Configuration Override +# ------------------------------------------------------------------------------ +# Copy to platformio_override.ini to activate overrides +# ------------------------------------------------------------------------------ +# Please visit documentation: https://docs.platformio.org/page/projectconf.html + +[platformio] +#default_envs = WLED_tasmota_1M # define as many as you need +default_envs = WLED_T-Display # define as many as you need +#---------- +# SAMPLE +#---------- +[env:WLED_T-Display] + +board = esp32dev +upload_speed = 921600 +monitor_speed = 115200 +platform = ${esp32.platform} +platform_packages = ${esp32.platform_packages} +build_unflags = ${common.build_unflags} +build_flags = ${common.build_flags} ${esp32.build_flags} -D WLED_RELEASE_NAME=\"WLED_T-Display\" ; -D IRPIN=4 ; -D RLYPIN=12 ; -D RLYMDE=1 +; -D WLED_DISABLE_BROWNOUT_DET +;PIN defines - uncomment and change, if needed: + -D DATA_PINS=2 +;or use this for multiple outputs +; -D DATA_PINS=1,3 + -D BTNPIN=35 +; -D IRPIN=4 +; -D RLYPIN=12 +; -D RLYMDE=1 +; -D RLYODRAIN=0 +; -D LED_BUILTIN=2 # GPIO of built-in LED +lib_deps = ${esp32.lib_deps} +custom_usermods = audioreactive TTGO-T-Display +monitor_filters = esp32_exception_decoder +board_build.partitions = ${esp32.default_partitions} diff --git a/usermods/TTGO-T-Display/set_build_flags.py b/usermods/TTGO-T-Display/set_build_flags.py new file mode 100644 index 0000000000..c88bcbfaa9 --- /dev/null +++ b/usermods/TTGO-T-Display/set_build_flags.py @@ -0,0 +1,50 @@ +# Select target board +# Ref: https://github.com/Bodmer/TFT_eSPI/wiki/Installing-on-PlatformIO#4-configure-library +# These flags are passed to this library and the TFT_eSPI library only + +Import("env") +import os + + +# Add pin definitions to whole project environment if they haven't otherwise been specified +# WM: This is a feature of the original usermod; I'm not sure if it's globally applicable.. +global_env = DefaultEnvironment() +global_defines = global_env.get("CPPDEFINES", []) +if "BTNPIN" not in [v[0] for v in global_defines if isinstance(v, tuple)]: + global_env.Append(CPPDEFINES=[("BTNPIN", "35")]) + +# Select display setup +display_setup = global_env.GetProjectOption("custom_display_setup","User_Setups/Setup25_TTGO_T_Display.h") + +# Resolve this file's path +def find_in_paths(filename, paths): + for path in paths: + fullpath = os.path.join(str(path), filename) + if os.path.isfile(fullpath): + return fullpath + return None + +lib_builders = env.GetLibBuilders() +if os.path.isfile(display_setup): + display_setup_path = display_setup +else: + search_paths = [global_env["PROJECT_SRC_DIR"], + global_env["PROJECT_INCLUDE_DIR"], + *[incdir for lb in lib_builders for incdir in lb.get_include_dirs()]] + + display_setup_path = find_in_paths(display_setup, search_paths) + +if display_setup_path is None: + print(f"Unable to find {display_setup} in any include path - {[str(path) for path in search_paths]}!") + raise RuntimeError("Missing display setup; use 'User_Setups/something.h' for setups out of TFT_eSPI, or put your setup in wled00") + +def add_display_setup(tgt_env): + tgt_env.Append(CPPDEFINES=[("USER_SETUP_LOADED", "1")]) + tgt_env.Append(CCFLAGS=f"-include {display_setup_path}") + +# Add it for this library and the TFT_eSPI dependency +add_display_setup(env) +for lb in lib_builders: + if lb.name == "TFT_eSPI": + add_display_setup(lb.env) + break diff --git a/usermods/TTGO-T-Display/usermod.cpp b/usermods/TTGO-T-Display/usermod.cpp index d8dcb29996..524767823e 100644 --- a/usermods/TTGO-T-Display/usermod.cpp +++ b/usermods/TTGO-T-Display/usermod.cpp @@ -17,89 +17,93 @@ * when a change in the dipslayed info is detected (within a 5 second interval). */ - -//Use userVar0 and userVar1 (API calls &U0=,&U1=, uint16_t) - #include "wled.h" -#include #include +#include #include "WiFi.h" #include -#ifndef TFT_DISPOFF -#define TFT_DISPOFF 0x28 -#endif +// #ifndef TFT_DISPOFF +// #define TFT_DISPOFF 0x28 +// #endif -#ifndef TFT_SLPIN -#define TFT_SLPIN 0x10 -#endif +// #ifndef TFT_SLPIN +// #define TFT_SLPIN 0x10 +// #endif -#define TFT_MOSI 19 -#define TFT_SCLK 18 -#define TFT_CS 5 -#define TFT_DC 16 -#define TFT_RST 23 +// #define TFT_MOSI 19 +// #define TFT_SCLK 18 +// #define TFT_CS 5 +// #define TFT_DC 16 +// #define TFT_RST 23 + +//#define TFT_BL 4 // Display backlight control pin +//#define ADC_EN 14 // Used for enabling battery voltage measurements - not used in this program +//#define WLED_WATCHDOG_TIMEOUT 3 + +// How often we are redrawing screen +#define USER_LOOP_REFRESH_RATE_MS 5000 -#define TFT_BL 4 // Display backlight control pin -#define ADC_EN 14 // Used for enabling battery voltage measurements - not used in this program +class TTGO_T_DisplayMod : public Usermod { -TFT_eSPI tft = TFT_eSPI(135, 240); // Invoke custom library + // Member variables + TFT_eSPI tft; // Invoke custom library + // 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; + + long lastUpdate_mod = 0; + long lastRedraw = 0; + bool displayTurnedOff = false; + +public: + +TTGO_T_DisplayMod() : Usermod() +{} //gets called once at boot. Do all initialization that doesn't depend on network here -void userSetup() { - Serial.begin(115200); - Serial.println("Start"); +void setup() override { + DEBUG_PRINTLN("Start"); tft.init(); tft.setRotation(3); //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.setTextSize(2); + //tft.setTextSize(1); tft.setTextColor(TFT_WHITE); tft.setCursor(1, 10); tft.setTextDatum(MC_DATUM); tft.setTextSize(3); + //tft.setTextSize(1); tft.print("Loading..."); + DEBUG_PRINTLN("Loading..."); if (TFT_BL > 0) { // TFT_BL has been set in the TFT_eSPI library in the User Setup file TTGO_T_Display.h pinMode(TFT_BL, OUTPUT); // Set backlight pin to output mode - digitalWrite(TFT_BL, HIGH); // Turn backlight on. + digitalWrite(TFT_BL, TFT_BACKLIGHT_ON); // Turn backlight on. } // tft.setRotation(3); } -// 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; -uint8_t tftcharwidth = 19; // Number of chars that fit on screen with text size set to 2 - -long lastUpdate = 0; -long lastRedraw = 0; -bool displayTurnedOff = false; -// How often we are redrawing screen -#define USER_LOOP_REFRESH_RATE_MS 5000 -void userLoop() { +void loop() override { // Check if we time interval for redrawing passes. - if (millis() - lastUpdate < USER_LOOP_REFRESH_RATE_MS) { + if (millis() - lastUpdate_mod < USER_LOOP_REFRESH_RATE_MS) { return; } - lastUpdate = millis(); + lastUpdate_mod = millis(); // Turn off display after 5 minutes with no change. if(!displayTurnedOff && millis() - lastRedraw > 5*60*1000) { - digitalWrite(TFT_BL, LOW); // Turn backlight off. + digitalWrite(TFT_BL, !TFT_BACKLIGHT_ON); // Turn backlight off. displayTurnedOff = true; } @@ -140,6 +144,7 @@ void userLoop() { knownPalette = strip.getMainSegment().palette; tft.fillScreen(TFT_BLACK); + //tft.setTextColor(TFT_WHITE); tft.setTextSize(2); // First row with Wifi name tft.setCursor(1, 1); @@ -156,7 +161,7 @@ void userLoop() { // tft.print(apPass); // else // tft.print(knownIp); - + DEBUG_PRINTLN("Print known AP"); if (apActive) { tft.print("AP IP: "); tft.print(knownIp); @@ -165,6 +170,7 @@ void userLoop() { tft.print(apPass); } else { + DEBUG_PRINTLN("Print IP"); tft.print("IP: "); tft.print(knownIp); tft.setCursor(1,46); @@ -180,16 +186,27 @@ void userLoop() { char lineBuffer[tftcharwidth+1]; extractModeName(knownMode, JSON_mode_names, lineBuffer, tftcharwidth); tft.print(lineBuffer); + DEBUG_PRINTLN("Print mode name"); // Fourth row with palette name tft.setCursor(1, 90); extractModeName(knownPalette, JSON_palette_names, lineBuffer, tftcharwidth); tft.print(lineBuffer); + DEBUG_PRINTLN("Print palette"); // Fifth row with estimated mA usage tft.setCursor(1, 112); // Print estimated milliamp usage (must specify the LED type in LED prefs for this to be a reasonable estimate). - tft.print(strip.currentMilliamps); + //tft.print(strip.currentMilliamps); + tft.print(BusManager::currentMilliamps()); + DEBUG_PRINTLN(BusManager::currentMilliamps()); + DEBUG_PRINTLN(" mA (estimated)"); + //tft.print("test "); tft.print("mA (estimated)"); + DEBUG_PRINTLN("Print estimated current"); } +}; // TTGO_T_DisplayMod + +static TTGO_T_DisplayMod usermod_ttgo_t_display; +REGISTER_USERMOD(usermod_ttgo_t_display); diff --git a/wled00/usermod.cpp b/wled00/usermod.cpp index 40fda83b07..60199d09c6 100644 --- a/wled00/usermod.cpp +++ b/wled00/usermod.cpp @@ -11,19 +11,19 @@ //Use userVar0 and userVar1 (API calls &U0=,&U1=, uint16_t) //gets called once at boot. Do all initialization that doesn't depend on network here -void userSetup() +__attribute__((weak)) void userSetup() { } //gets called every time WiFi is (re-)connected. Initialize own network interfaces here -void userConnected() +__attribute__((weak)) void userConnected() { } //loop. You can use "if (WLED_CONNECTED)" to check for successful connection -void userLoop() +__attribute__((weak)) void userLoop() { }