New usermod to support the TTGO T-Display (ESP32 based board with integrated TFT display) (#957)
* Adding new usermod for TTGO T-DIsplay. * Finalizing the code * Modified and cleaned up readme.md file * Fixes to platformio.ini to restore back to previous state * Cleaned up comments in usermod file
This commit is contained in:
parent
6e49cc54ac
commit
7e01d113d8
@ -167,6 +167,8 @@ lib_deps =
|
|||||||
AsyncTCP@1.0.3
|
AsyncTCP@1.0.3
|
||||||
Esp Async WebServer@1.2.0
|
Esp Async WebServer@1.2.0
|
||||||
IRremoteESP8266@2.7.3
|
IRremoteESP8266@2.7.3
|
||||||
|
#For use of the TTGO T-Display ESP32 Module with integrated TFT display uncomment the following line
|
||||||
|
#TFT_eSPI
|
||||||
#For use SSD1306 OLED display uncomment following
|
#For use SSD1306 OLED display uncomment following
|
||||||
#U8g2@~2.27.2
|
#U8g2@~2.27.2
|
||||||
#For Dallas sensor uncomment following 2 lines
|
#For Dallas sensor uncomment following 2 lines
|
||||||
|
59
usermods/TTGO-T-Display/README.md
Normal file
59
usermods/TTGO-T-Display/README.md
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
# TTGO T-Display ESP32 with 240x135 TFT via SPI with TFT_eSPI
|
||||||
|
This usermod allows use of the TTGO T-Display ESP32 module with integrated 240x135 display
|
||||||
|
for controlling WLED and showing the following information:
|
||||||
|
* Current SSID
|
||||||
|
* IP address if obtained
|
||||||
|
* in AP mode and turned off lightning AP password is shown
|
||||||
|
* Current effect
|
||||||
|
* Current palette
|
||||||
|
|
||||||
|
Usermod based on a rework of the ssd1306_i2c_oled_u8g2 usermod from the WLED repo.
|
||||||
|
|
||||||
|
## Hardware
|
||||||
|
![Hardware](assets/ttgo_hardware1.png)
|
||||||
|
|
||||||
|
## Github reference for TTGO-Tdisplay
|
||||||
|
|
||||||
|
* [TTGO T-Display](https://github.com/Xinyuan-LilyGO/TTGO-T-Display)
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
Functionality checked with:
|
||||||
|
* TTGO T-Display
|
||||||
|
* PlatformIO
|
||||||
|
* Group of 4 individual Neopixels from Adafruit, and a full string of 68 LEDs.
|
||||||
|
|
||||||
|
## 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
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
### 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)
|
||||||
|
NOTE: I am relatively new to Platformio and VS Code, but I find that in order to get the project populated with the TFT_eSPI library (so the following changes can be made), I need to attempt an initial build that I know will fail. There is probably a better way to accomplish this, but it worked for me. Once the first build fails, the `User_Setup_Select.h` file can be found in the `/.pio/libdeps/esp32dev/TFT_eSPI_ID1559` folder.
|
||||||
|
|
||||||
|
Modify the `User_Setup_Select.h` file as follows:
|
||||||
|
* Comment out the following line (which is the 'default' setup file):
|
||||||
|
```ini
|
||||||
|
//#include <User_Setup.h> // Default setup is root library folder
|
||||||
|
```
|
||||||
|
* Uncomment the following line (which points to the setup file for the TTGO T-Display):
|
||||||
|
```ini
|
||||||
|
#include <User_Setups/Setup25_TTGO_T_Display.h> // Setup file for ESP32 and TTGO T-Display ST7789V SPI bus TFT
|
||||||
|
```
|
||||||
|
|
||||||
|
Run the build again and it should complete correctly.
|
||||||
|
|
||||||
|
## Arduino IDE
|
||||||
|
- UNTESTED
|
BIN
usermods/TTGO-T-Display/assets/ttgo_hardware1.png
Normal file
BIN
usermods/TTGO-T-Display/assets/ttgo_hardware1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 686 KiB |
8
usermods/TTGO-T-Display/platformio_override.ini
Normal file
8
usermods/TTGO-T-Display/platformio_override.ini
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[env:esp32dev]
|
||||||
|
build_flags = ${common.build_flags_esp32}
|
||||||
|
; PIN defines - uncomment and change, if needed:
|
||||||
|
; -D LEDPIN=2
|
||||||
|
-D BTNPIN=35
|
||||||
|
; -D IR_PIN=4
|
||||||
|
; -D RLYPIN=12
|
||||||
|
; -D RLYMDE=1
|
214
usermods/TTGO-T-Display/usermod.cpp
Normal file
214
usermods/TTGO-T-Display/usermod.cpp
Normal file
@ -0,0 +1,214 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
* This file allows you to add own functionality to WLED more easily
|
||||||
|
* See: https://github.com/Aircoookie/WLED/wiki/Add-own-functionality
|
||||||
|
* EEPROM bytes 2750+ are reserved for your custom use case. (if you extend #define EEPSIZE in const.h)
|
||||||
|
* bytes 2400+ are currently ununsed, but might be used for future wled features
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Pin 2 of the TTGO T-Display serves as the data line for the LED string.
|
||||||
|
* Pin 35 is set up as the button pin in the platformio_overrides.ini file.
|
||||||
|
* The button can be set up via the macros section in the web interface.
|
||||||
|
* I use the button to cycle between presets.
|
||||||
|
* The Pin 35 button is the one on the RIGHT side of the USB-C port on the board,
|
||||||
|
* when the port is oriented downwards. See readme.md file for photo.
|
||||||
|
* The display is set up to turn off after 5 minutes, and turns on automatically
|
||||||
|
* 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 <TFT_eSPI.h>
|
||||||
|
#include <SPI.h>
|
||||||
|
#include "WiFi.h"
|
||||||
|
#include <Wire.h>
|
||||||
|
|
||||||
|
#ifndef TFT_DISPOFF
|
||||||
|
#define TFT_DISPOFF 0x28
|
||||||
|
#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_BL 4 // Display backlight control pin
|
||||||
|
#define ADC_EN 14 // Used for enabling battery voltage measurements - not used in this program
|
||||||
|
|
||||||
|
TFT_eSPI tft = TFT_eSPI(135, 240); // Invoke custom library
|
||||||
|
|
||||||
|
//gets called once at boot. Do all initialization that doesn't depend on network here
|
||||||
|
void userSetup() {
|
||||||
|
Serial.begin(115200);
|
||||||
|
Serial.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.setTextColor(TFT_WHITE);
|
||||||
|
tft.setCursor(1, 10);
|
||||||
|
tft.setTextDatum(MC_DATUM);
|
||||||
|
tft.setTextSize(2);
|
||||||
|
tft.print("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.
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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() {
|
||||||
|
|
||||||
|
// 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.setCursor(1, 10);
|
||||||
|
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 IP or Psssword
|
||||||
|
tft.setCursor(1, 40);
|
||||||
|
// Print password in AP mode and if led is OFF.
|
||||||
|
if (apActive && bri == 0)
|
||||||
|
tft.print(apPass);
|
||||||
|
else
|
||||||
|
tft.print(knownIp);
|
||||||
|
|
||||||
|
// Third row with mode name
|
||||||
|
tft.setCursor(1, 70);
|
||||||
|
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.print(singleJsonSymbol);
|
||||||
|
printedChars++;
|
||||||
|
}
|
||||||
|
if ((qComma > knownMode) || (printedChars > tftcharwidth - 1))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Fourth row with palette name
|
||||||
|
tft.setCursor(1, 100);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user